📦

ESP32 で FreeRTOS - Hello World! から Wifi まで

2023/01/14に公開

ここからスタート

FreeRTOS を触る前に、まずは ESP32 の使い方を理解したいので AWS のサイトにある、Espressif ESP32-WROOM-32SE の開始方法から進めていくことにする。

事前準備

AWSのサイトからは Espressif のドキュメント v4.2 を参照しているが、現時点では v5.0 が最新版なので、この手順に沿ってやっていくpython cmake ninjaなどのセットアップ。

ESP-IDFをインストール

Espressif IoT Development Framework. Official development framework for Espressif SoCs.

ビルドのフロントエンドだったり、デバイスとやりとりするためのツールっぽい。

Get Startedでは VS Code と Eclipse 経由でのインストールを激推ししてくるが、自分は vim 派なのでスルーする。

We highly recommend installing the ESP-IDF through your favorite IDE.

  • Eclipse Plugin
  • VSCode Extension

普通にインストールしていく。

git clone -b release/v5.0 --recursive https://github.com/espressif/esp-idf.git

ここは結構時間かかるのでコーヒータイム ☕️

コンパイラーやデバッガーなどを設定していく

インストール

./install.sh esp32

環境変数を設定

. $HOME/Projects/esp/esp-idf/export.sh

なんかエラーが...

Setting IDF_PATH to '/Users/masainox/Projects/esp/esp-idf'
Detecting the Python interpreter
Checking "python3" ...
Python 3.10.9
"python3" has been detected
Checking Python compatibility
Checking other ESP-IDF version.
ERROR: tool riscv32-esp-elf-gdb has no installed versions. Please run '/usr/local/opt/python@3.10/bin/python3.10 /Users/masainox/Projects/esp/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool xtensa-esp32s2-elf has no installed versions. Please run '/usr/local/opt/python@3.10/bin/python3.10 /Users/masainox/Projects/esp/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool xtensa-esp32s3-elf has no installed versions. Please run '/usr/local/opt/python@3.10/bin/python3.10 /Users/masainox/Projects/esp/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool riscv32-esp-elf has no installed versions. Please run '/usr/local/opt/python@3.10/bin/python3.10 /Users/masainox/Projects/esp/esp-idf/tools/idf_tools.py install' to install it.

ERRORの言うがままに実行

/usr/local/opt/python@3.10/bin/python3.10 /Users/masainox/Projects/esp/esp-idf/tools/idf_tools.py install

エイリアスも設定

.zshrc
alias get_idf='. $HOME/Projects/esp/esp-idf/export.sh'

Hello Worldプロジェクトをやる

cp -r $IDF_PATH/examples/get-started/hello_world .

他の例はここにあるのであとで試そう。

デバイスに接続

ESP32 を USB で繋ぐとシリアルポートがでてくる

ls /dev/cu*
/dev/cu.BLTH			/dev/cu.Bluetooth-Incoming-Port	/dev/cu.usbserial-0001

idf.pyを使おうと思ったが、見つからない... と思っていたら、さっき設定したエイリアスget_idf つまり . $HOME/Projects/esp/esp-idf/export.shを実行すると idf.py が作られた。

プロジェクトをセットアップしていく。

cd ~/Project/esp/hello_world
idf.py set-target esp32
idf.py menuconfig

とりあえず menuconfig はデフォルトのままビルドする。

idf.py build

ポートは /dev/cu.usbserial-0001 なので以下のように flash する。

idf.py -p /dev/cu.usbserial-0001 flash 

エラーが発生!

A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
FAILED: CMakeFiles/flash /Users/masainox/Projects/esp/hello_world/build/CMakeFiles/flash 
cd /Users/masainox/Projects/esp/esp-idf/components/esptool_py && /usr/local/Cellar/cmake/3.25.1/bin/cmake -D IDF_PATH=/Users/masainox/Projects/esp/esp-idf -D "SERIAL_TOOL=/Users/masainox/.espressif/python_env/idf5.0_py3.10_env/bin/python;;/Users/masainox/Projects/esp/esp-idf/components/esptool_py/esptool/esptool.py;--chip;esp32" -D "SERIAL_TOOL_ARGS=--before=default_reset;--after=hard_reset;write_flash;@flash_args" -D WORKING_DIRECTORY=/Users/masainox/Projects/esp/hello_world/build -P /Users/masainox/Projects/esp/esp-idf/components/esptool_py/run_serial_tool.cmake
ninja: build stopped: subcommand failed.

ブートモードをダウンロードモードにせよとのこと。ググっていたら、解決策を発見。USBポートの横のボタンを押しながらflashせよと。え?おまえ、ボタンだったのか!

よく見るとExpressifのドキュメントにもボタン押せって書いてあるこの図の、Boot button っていうやつ。

やってみる

idf.py -p /dev/cu.usbserial-0001 flash                                          
Executing action: flash
Running ninja in directory /Users/masainox/Projects/esp/hello_world/build
Executing "ninja flash"...
[1/5] cd /Users/masainox/Projects/esp/hello_world/build/esp-idf/esptool_py && /Users/masainox/.espressif/python_env/idf5.0_py3.10_env/bin/python /Users/masainox/Projects/esp/esp-idf/components/partition_table/check_sizes.py --offset 0x8000 partition --type app /Users/masainox/Projects/esp/hello_world/build/partition_table/partition-table.bin /Users/masainox/Projects/esp/hello_world/build/hello_world.bin
hello_world.bin binary size 0x2b440 bytes. Smallest app partition is 0x100000 bytes. 0xd4bc0 bytes (83%) free.
[2/5] Performing build step for 'bootloader'
[1/1] cd /Users/masainox/Projects/esp/hello_world/build/bootloader/esp-idf/esptool_py && /Users/masainox/.espressif/python_env/idf5.0_py3.10_env/bin/python /Users/masainox/Projects/esp/esp-idf/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x1000 /Users/masainox/Projects/esp/hello_world/build/bootloader/bootloader.bin
Bootloader binary size 0x66f0 bytes. 0x910 bytes (8%) free.
[3/5] No install step for 'bootloader'
[4/5] Completed 'bootloader'
[4/5] cd /Users/masainox/Projects/esp/esp-idf/components/esptool_py && /usr/local/Cellar/cmake/3.25.1/bin/cmake -D IDF_PATH=/Users/masainox/Projects/esp/esp-idf -D "SERIAL_TOOL=/Users/masainox/.espressif/python_env/idf5.0_py3.10_env/bin/python;;/Users/masainox/Projects/esp/esp-idf/components/esptool_py/esptool/esptool.py;--chip;esp32" -D "SERIAL_TOOL_ARGS=--before=default_reset;--after=hard_reset;write_flash;@flash_args" -D WORKING_DIRECTORY=/Users/masainox/Projects/esp/hello_world/build -P /Users/masainox/Projects/esp/esp-idf/components/esptool_py/run_serial_tool.cmake
esptool esp32 -p /dev/cu.usbserial-0001 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 bootloader/bootloader.bin 0x10000 hello_world.bin 0x8000 partition_table/partition-table.bin
esptool.py v4.4
Serial port /dev/cu.usbserial-0001
Connecting......
Chip is ESP32-D0WDQ6 (revision v1.0)
Features: WiFi, BT, Dual Core, Coding Scheme None
Crystal is 40MHz
MAC: 30:ae:a4:08:94:cc
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00007fff...
Flash will be erased from 0x00010000 to 0x0003bfff...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 26352 bytes to 16398...
Writing at 0x00001000... (50 %)
Writing at 0x000076e9... (100 %)
Wrote 26352 bytes (16398 compressed) at 0x00001000 in 0.8 seconds (effective 280.9 kbit/s)...
Hash of data verified.
Compressed 177216 bytes to 93931...
Writing at 0x00010000... (16 %)
Writing at 0x0001b4a1... (33 %)
Writing at 0x00020d88... (50 %)
Writing at 0x000264f1... (66 %)
Writing at 0x0002efa5... (83 %)
Writing at 0x00036d00... (100 %)
Wrote 177216 bytes (93931 compressed) at 0x00010000 in 2.8 seconds (effective 500.1 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 408.1 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Done

お、なんかいけたっぽい。チップはESP32-D0WDQ6 (revision v1.0)らしい。では、ここでブートログをみて、Hello world! が出力されているか確認

idf.py -p /dev/cu.usbserial-0001 monitor
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7008
load:0x40078000,len:15408
load:0x40080400,len:3840
0x40080400: _init at ??:?

entry 0x4008064c
I (27) boot: ESP-IDF v5.0-494-g490216a2ac 2nd stage bootloader
I (27) boot: compile time 13:18:48
I (27) boot: chip revision: v1.0
I (31) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (38) boot.esp32: SPI Speed      : 40MHz
I (43) boot.esp32: SPI Mode       : DIO
I (48) boot.esp32: SPI Flash Size : 2MB
I (52) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (61) boot: ## Label            Usage          Type ST Offset   Length
I (68) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (76) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (83) boot:  2 factory          factory app      00 00 00010000 00100000
I (91) boot: End of partition table
I (95) boot_comm: chip revision: 1, min. application chip revision: 0
I (102) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0823ch ( 33340) map
I (123) esp_image: segment 1: paddr=00018264 vaddr=3ffb0000 size=01e7ch (  7804) load
I (126) esp_image: segment 2: paddr=0001a0e8 vaddr=40080000 size=05f30h ( 24368) load
I (140) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=15ba0h ( 88992) map
I (172) esp_image: segment 4: paddr=00035bc8 vaddr=40085f30 size=05854h ( 22612) load
I (188) boot: Loaded app from partition at offset 0x10000
I (188) boot: Disabling RNG early entropy source...
I (199) cpu_start: Pro cpu up.
I (199) cpu_start: Starting app cpu, entry point is 0x40081048
0x40081048: call_start_cpu1 at /Users/masainox/Projects/esp/esp-idf/components/esp_system/port/cpu_start.c:142

I (186) cpu_start: App cpu up.
I (214) cpu_start: Pro cpu start user code
I (214) cpu_start: cpu freq: 160000000 Hz
I (214) cpu_start: Application information:
I (218) cpu_start: Project name:     hello_world
I (224) cpu_start: App version:      1
I (228) cpu_start: Compile time:     Jan 14 2023 13:18:33
I (234) cpu_start: ELF file SHA256:  78d999e58d1fa30b...
I (240) cpu_start: ESP-IDF:          v5.0-494-g490216a2ac
I (247) heap_init: Initializing. RAM available for dynamic allocation:
I (254) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (260) heap_init: At 3FFB2770 len 0002D890 (182 KiB): DRAM
I (266) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (272) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (279) heap_init: At 4008B784 len 0001487C (82 KiB): IRAM
I (286) spi_flash: detected chip: gd
I (289) spi_flash: flash io: dio
W (293) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (307) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision v1.0, 2MB external flash
Minimum free heap size: 301716 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...

リブートし続けるので、Ctrl + ] で止める。よく見ると、あるな、下の方に。これで Hello world! は成功、でいいのかな。

Wifi に接続

Wifi のスキャン

esp-idf/examples/wifi/scan を試した。idf.py -p /dev/cu.usbserial-0001 monitor で普通に周辺の SSID がスキャンできていることが確認できる。

Wifi へ接続

esp-idf/examples/wifi/getting_started/stationを試した。idf.py menuconfigExample Configuration から SSID と パスワードがコンフィグできる。すぐに問題なくつながった。monitor で Wifi に繋がって、IP も取れていることが確認できる。

I (806) wifi:enable tsf
I (806) wifi station: wifi_init_sta finished.
I (816) wifi:new:<7,1>, old:<1,0>, ap:<255,255>, sta:<7,1>, prof:1
I (816) wifi:state: init -> auth (b0)
I (826) wifi:state: auth -> init (8a0)
I (826) wifi:new:<7,0>, old:<7,1>, ap:<255,255>, sta:<7,1>, prof:1
I (836) wifi station: retry to connect to the AP
I (836) wifi station: connect to the AP fail
I (3246) wifi station: retry to connect to the AP
I (3246) wifi station: connect to the AP fail
I (3256) wifi:new:<7,1>, old:<7,0>, ap:<255,255>, sta:<7,1>, prof:1
I (3256) wifi:state: init -> auth (b0)
I (3256) wifi:state: auth -> assoc (0)
I (3266) wifi:state: assoc -> run (10)
I (3296) wifi:connected with deco, aid = 3, channel 7, 40U, bssid = d8:07:b6:60:8c:fa
I (3296) wifi:security: WPA2-PSK, phy: bgn, rssi: -58
I (3306) wifi:pm start, type: 1

I (3376) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (3926) wifi:<ba-add>idx:0 (ifx:0, d8:07:b6:60:8c:fa), tid:6, ssn:3, winSize:64
I (4806) esp_netif_handlers: sta ip: 192.168.68.106, mask: 255.255.255.0, gw: 192.168.68.1
I (4806) wifi station: got ip:192.168.68.106
I (4806) wifi station: connected to ap SSID:******* password:**********

今回はとりあえずここまで。

Discussion