ESP32/M5Stack の開発環境構築(esp-idf と Arduino Core)

2020/1/19 更新

ESP32/M5Stack 開発環境構成の整理がてら構築手順をまとめてみました。Arduino IDE は使わずに VS Code でプログラムがかけるところまで書いてみます。

Windows 向けに書いていますが、ツールチェインの導入部分が異なるだけで他の OS でも基本的な考え方や手順は同じです。

ひとつずつ確認しながら進む手順になっていますので、フルコンパイルが何度かかかり少し時間がかかりますがご勘弁を。慣れてきたら飛ばしてやってください。

また、この記事は ESP32/M5Stack 系のツールチェインやライブラリー依存関係の参考にもなるかもしれません。(PlatformIO や Arduino IDE + VS Code Arduino extention などが行っている内部的な動作が分かりますので、コンパイルエラーなどが出たときに対応がしやすくなると思います)

参考リポジトリー

本手順を元につくられた M5Stack サンプルアプリとビルド手順は次の github リポジトリーから参照できます。手順とソースコードの構成を合わせて見ると分かりやすいと思います。

https://github.com/h1romas4/m5stack-synth-emulation

M5Stack Core2 向けの記事

M5Stack Core2 環境構築は、以下の記事を参考にしてください。(本記事の M5Stack Core から使うライブラリーなどが変わっています)

ESP32/M5Stack の開発系の構成

ESP32/M5Stack オフィシャル開発系の構成は次のようになっています。

  • xtensa-esp32 – ツールチェイン(gccクロスコンパイラ) Windows/Linux/macOS 用に分かれています。
  • esp-idf – ESP32 用のフレームワーク(FreeRTOS + ライブラリ+ 転送ツール等)
  • Arduino Core for the ESP32– ESP32 で Arduino 風の関数やコンポーネントを使うライブラリ(要 esp-idf)
  • M5Stack-IDF – M5Stack から提供される esp-idf + Arduino Core + M5用のライブラリー

Arduino Core for the ESP32 に関しては esp-idf の追加コンポーネントのような形となっていますので ESP32 開発で必須なのは xtensa-esp32 と esp-idf です。

拡張として Arduino Core は esp-idf に依存し、さらに M5Stack は Arduino Core に依存しているという構成になります。(といってもプロジェクトテンプレートがうまくできているので導入は簡単です)

バージョン依存

Arduino Core、M5Stack は上位モジュールを参照しているため、バージョンによる依存関係があります。この記事の解説では次のバージョンが導入されます。

esp-idfv3.1.3
Arduino Core1.0.0
M5Stack0.2.1

2020/1 現在の新しいバージョンの組み合わせは以下のようになっているようです。

esp-idfv3.2.3
Arduino Core1.0.4
M5Stack0.2.9

手順でも補足していますが、最新にする場合は esp-idf 及び Arduino Core の git clone 時のバージョンを変更してください。なお、Arduino Core のリリースに、依存する esp-idf のバージョンがかかれています。

本記事に対応した github の参考リポジトリーではビルド環境依存を防ぐため、リポジトリーに esp-idf も submodule で加え、後述する IDF_PATH 環境変数の切り替えをビルド手順に加え、数行のコマンドでビルドできるようにしています。

git clone --recursive https://github.com/h1romas4/m5stack-synth-emulation.git
cd m5stack-synth-emulation
# This repository includes eps-idf v3.2.3
export IDF_PATH=$(pwd)/esp-idf
make

また、Github Actions の機能を使ったスクリプトでビルドしてできたバイナリーを自動的にリリースできるようにしてみました。

ツールチェインの導入

まずコンパイラや周辺ツールを含むツールチェインを導入します。

Windows 上の任意の場所に開発系の作業フォルダーを作成し、Toolchain Setup からダウンロードしたツールチェインの .zip を展開します。

Toolchain Setup

The quick setup is to download the Windows all-in-one toolchain & MSYS2 zip file from dl.espressif.com:

執筆時点での安定版ツールチェインは

esp32_win32_msys2_environment_and_toolchain-20181001.zip

でした。

本手順では作業用ディレクトリを以下のパスにします。

C:\develop\esp

ツールチェインの .zip が展開できたら

C:\develop\esp\msys32

の形にフォルダーを移動後、以下のファイルをダブルクリックしてビルド操作用のターミナルを起動します。(この後はこの窓で作業していきます)

C:\develop\esp\msys32\mingw32.exe

mingw32 が起動したらホームディレクトリに作業用のディレクトリを作成してカレントディレクトリを移しておきます

$ mkdir ~/esp
$ cd ~/esp

なおこれらの Windows 的なファイルの実態は

C:\develop\esp\msys32\home\[ユーザー名]\esp

になります。またツールチェイン(コンパイラ)は

C:\develop\esp\msys32\opt\xtensa-esp32-elf\bin

にあり事前にパスが通っています。

それぞれをエクスプローラーで確認しておきましょう。

esp-idf の導入

引き続き mingw シェル上で git を使い esp-idf を導入します。

Get ESP-IDF

$ cd ~/esp
$ git clone -b v3.1.3 --recursive https://github.com/espressif/esp-idf.git

ディレクトリ esp-idf が作成され esp-idf が格納されます。

git clone で指定している v3.1.3 が esp-idf のバージョンになります。より新しいバージョンを指定するには v3.2.3 などとします。

前述の「バージョン依存」の通り Arduino Core や M5Stack は依存する esp-idf のバージョンが決まっていますので注意します。これらを利用しない場合は任意の最新バージョンの esp-idf を使うことができます。

なお、esp-idf は v3.3 系が LTS(長期サポート版)になっているようです。

ESP-IDF Release v3.3 (LTS)

Version 3.3 is the first ESP-IDF Long Term Support release. ESP-IDF v3.3.x will be supported for 2.5 years, until March 2022.

次に OS の IDF_PATH 環境変数に上記で得られた esp-idf のパスを設定します。(この機能により複数の esp-idf のバージョンを切り替えることができます)

公式では mingw 上のシェル環境に設定することになっていますが、Windows 側で設定した方が後述の VS Code からも見ることができるので、システム詳細設定でユーザ環境設定で IDF_PATH を追加します。

新規ボタンで IDF_PATH を追加し

C:\develop\esp\msys32\home\[ユーザー名]\esp\esp-idf

を設定します。できたらいったん mingw32 ターミナルを exit やウインドウの☒で落として再び、

C:\develop\esp\msys32\mingw32.exe

をダブルクリックして再起動し設定を反映させます。

$ echo $IDF_PATH
# 設定した値が取れれば OK!
C:\develop\esp\msys32\home\hirom\esp\esp-idf

M5Stack の場合はこの後は飛ばし、手順「M5Stack テンプレート のコピー」まで進んでください。

esp-idf 開発の テンプレートとなる hello world ソースファイルをコピー

引き続き mingw32 シェル上で、テンプレートとなるソースファイルをコピーして開発の準備をします。

$ cd ~/esp
$ cp -r $IDF_PATH/examples/get-started/hello_world .
$ cd hello_world
$ make menuconfig

make 設定のメニューが表示されますのであれば必要な設定をします。(ここでは Component Config > ESP32-specific > CPU frequrncy で CPU クロックを 160MHz から 240MHz に変えてみました)

<Exit> で終了させるとプロジェクトフォルダーの sdkconfig ファイルが更新されますのでいったんここでコンパイルしてみます。 sdkconfig 更新後のコンパイルはフルコンパイルになりますので少し時間がかかります。

$ make -j4
# エラーがでなければコンパイル成功
To flash all build output, run 'make flash' or:
python /mnt/c/develop/esp32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyS3 --baud 115200 --before default_r
eset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /mnt/c/develop/esp32/hello_world/build/b
ootloader/bootloader.bin 0x10000 /mnt/c/develop/esp32/hello_world/build/hello-world.bin 0x8000 /mnt/c/develop/esp32/hello_world/build/partit
ions_singleapp.bin

また、menuconfig では使うコンポーネントの選択を Component config 項から行うことができます。もしコンパイル時にヘッダーファイルが足りないといったエラーがでた場合は、プログラムで使っているコンポーネントを有効にします。

これらの設定も sdkconfig ファイルに保存されます。

Arduino Core を使わずに esp-idf のみで開発する方はこの手順で終了です。この後は飛ばし、手順「プログラムの転送」まで進みます。

Arduino Core コンポーネントの追加

ESP32 で Arduino Core を使う場合は、プロジェクトに components フォルダーを作成し Arduino Core コンポーネントを追加します。

To use as a component of ESP-IDF

$ cd ~/esp/hello_world
$ mkdir -p components
$ cd components
$ git clone -b 1.0.0 https://github.com/espressif/arduino-esp32.git arduino
$ cd arduino
$ git submodule update --init --recursive
$ cd ../..
$ make menuconfig

git clone で指定している 1.0.0 が Arduino Core for the ESP32 のバージョンになります。例えば esp-idf の導入で v3.2.3 を指定した場合は 1.0.4 などとなります。

もし後述の make が通らないようであれば esp-idf と Arduino Core の依存バージョンが不整合していますので最新の情報を確認してみてください。

Arduino Core コンポーネントを追加すると menuconfig に「Arduino Configuration」が追加されますので「Autostart Arduino setup and loop on boot」を enable にします。プログラムを loop/setup の Arduino 構成でかくことができるようになります。

また、デフォルトの sdkconfig であると Flash の容量が 2M 設定になっているので「Serial flasher config」から「Flash Size」を 4M に変更します

最後に Arduino Core で C++ の例外ハンドリングに依存しているソースがありますので設定を有効化します。「Compiler Options」から「Enable C++ Exceptions」

exit して menuconfig を終了させ sdkconfig を保存します。

Arduino Core を使った場合の main/hello_world_main.cpp は次のようになります。

ESP32 のテンプレートは hello_world_main.c と C になっていますので .cpp にリネームします。実ファイルが

C:\develop\esp\msys32\home\[ユーザ名]\esp\hello_world

にありますので任意の Windows 操作でリネーム、ファイルの編集を行います。

#include "Arduino.h"

void setup() {
    Serial.begin(115200);
}

void loop() {
    Serial.println("loop");
    delay(1000);
}

ソースファイルを変更後 make してみてコンパイルが通れば成功です。(Arduino Core が大きいので初回コンパイルには結構時間がかかります)

$ make clean # 手順の流れで ESP32 でコンパイルしているのでいったんクリーン 
$ make -j4
# エラーがでなければ OK!
To flash all build output, run 'make flash' or:
python /home/hirom/esp/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0xe000 /home/hirom/esp/hello_world/components/arduino/tools/partitions/boot_app0.bin 0x1000 /home/hirom/esp/hello_world/build/bootloader/bootloader.bin 0x10000 /home/hirom/esp/hello_world/build/hello-world.bin 0x8000 /home/hirom/esp/hello_world/build/default.bin

Arduino Code のセットアップはこの手順で終了です。「プログラムの転送 」まで進みます。

M5Stack テンプレートのコピー

M5Stack の場合は、M5 が事前に準備してくれている git リポジトリをクローンすることで Arduino Core と M5Stack-IDF コンポーネントが入った hello world テンプレートプロジェクトを得ることができます。

$ cd ~/esp
$ git clone --recursive https://github.com/m5stack/M5Stack-IDF.git
$ mv M5Stack-IDF/ hello_m5stack # 分りやすい名前にリネーム
$ cd hello_m5stack
$ make -j4
# ウイザードでいろいろ質問がありますが全て ENTER で OK
# コンパイル完了後、エラーがでなければ OK!
To flash all build output, run 'make flash' or:
python /home/hirom/esp/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/tty.SLAB_USBtoUART --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 /home/hirom/esp/hello_m5stack/components/arduino/tools/partitions/boot_app0.bin 0x1000 /home/hirom/esp/hello_m5stack/build/bootloader/bootloader.bin 0x10000 /home/hirom/esp/hello_m5stack/build/app-template.bin 0x8000 /home/hirom/esp/hello_m5stack/build/default.bin

M5Stack-IDF のリポジトリの Arduino Core 及び M5Stack ライブラリーは最新に追従していないようです。 esp-idf 3.1 より新しい esp-idf を使う場合は、make する前に以下のように依存コンポーネント(Arduino Core 及び M5Stack ライブラリー)をアップデートします。

例えば esp-idf v3.2.3 を指定した場合はそれぞれ 1.0.4 / 0.2.9 となります。

$ cd components/arduino
$ rm -Rf libraries/BLE/
$ git checkout 1.0.4 --recurse-submodules
$ cd ../m5stack/
$ git checkout 0.2.9 --recurse-submodules
$ cd ../..
$ make menuconfig # 質問は全てデフォルト(enter)で設定
# menuconfig から以下を有効化
Component Config -> mbedTLS -> TLS Key Exchange Methods -> 
  [*] Enable pre-shared-key ciphersuits
    [*] Enable PSK based ciphersuite modes
Component Config -> Bluetooth
  [*] Bluetooth
# menuconfig を終了させビルド
$ make -j4

初回コンパイルは少し時間がかかります。

プログラムの転送

コンパイルしたプログラムをマイコンへ転送してみます。

ESP32 Devkit もしくは M5stack を USB で PC に接続すると Windows 10 であれば自動的に認識して COM ポートが増えます。

COM ポート番号を覚えて make menuconfig から Serial flasher config でポートを設定します。

保存したら準備完了です。次のコマンドでプログラムの転送後リセットがかかりプログラムが動作します。 ハローハッピーワールド!

$ make -j4 flash monitor
# フラッシュ後起動すれば OK!
Flashing binaries to serial port COM3 (app at offset 0x10000 )...
esptool.py v2.6
Serial port COM3
Connecting....
Chip is ESP32D0WDQ6 (revision 1)

なお、起動後のシリアルモニターは ctrl + ] で停止することができます。

VS Code によるソースの編集とコンパイル

ここまでの手順でコンパイルとフラッシュができるようになりましたので、これを Visual Studio Code でソースの編集とともにできるようにします。

VS Code インストール後、拡張機能「ms-vscode.cpptools」を導入します。

次に編集したいプロジェクトをフォルダー指定で VS Code で開きます。この手順では M5Stack の手順つくったフォルダーを指定しています。

C:\develop\esp\msys32\home\[ユーザ名]\esp\hello_m5stack

プロジェクトフォルダーに上のように .vscode/settings.json を新規作成しワークスペース設定を次のようにします。

.vscode/settings.json
{
    "terminal.integrated.shell.windows": "C:\\develop\\esp\\msys32\\usr\\bin\\bash.exe",
    "terminal.integrated.env.windows": {
        "MSYSTEM": "MINGW32",
        "CHERE_INVOKING": "1"
    },
    "terminal.integrated.shellArgs.windows": [
        "--login"
    ],
    "C_Cpp.intelliSenseEngine": "Default"
}

設定後、統合ターミナルを開くと mingw32 がターミナルで使えるようになります。初回起動時は変更の可否を聞いてきますので「許可」して、再度統合ターミナルを起動し直してください。

mingw32 窓と同じ操作ができるようになりますので、make flash monitor してコンパイルからのフラッシュが VS Code 上からできるようになります。

次に C/C++ のコード補完ができるように 拡張機能「ms-vscode.cpptools」を設定します。先ほどつくった settings.json と同じ階層に c_cpp_properties.json を新規作成し次のように設定します。

.vscode/c_cpp_properties.json
{
    "configurations": [
        {
            "name": "ESP32",
            "includePath": [
                "${workspaceRoot}/**",
                "${IDF_PATH}/components/**",
                "${IDF_PATH}/../../../../opt/xtensa-esp32-elf/**"
            ],
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

設定後ソースファイル(main/main.cpp)を開くとソースコード補完などができるようになります。

portTICK_PERIOD_MS などのビルド時に生成される一部の define が vscode にエラー申告される場合はソースコード上部に以下のコードをいれると良いでしょう。(__INTELLISENSE__ 定数は vscode のインテリセンス実行時のみ設定されます)

#ifdef __INTELLISENSE__
#include "build/include/sdkconfig.h"
#endif

ここまでで環境構築はおしまいです。

さて、便宜上プロジェクトフォルダーを mingw32 配下

C:\develop\esp\msys32\home\[ユーザー名]\esp

において作業を進めましたが、設定完了後は Windows 上の任意の位置に配置できますのでお好みの場所に移したりコピーしたりしてください。(なお、フォルダーを移した場合はいったん make clean した後 make してください)

ESP32/M5Stack の資料

開発系のオフィシャル資料は次から参照することが出来ます。

  • ESP-IDF Programming Guide – esp-idf プログラミングガイド。ページトップが lasted バージョンのドキュメントになっていますので、必ず画面左下の選択が stable(お使いのバージョン) になっていることを確認してください。(結構 API 変わっています)
  • ESP32 Technical Reference Manual – ESP32 ハードウェアに直接アクセスする場合など、EPS32 そのものについて記載があるテクニカルマニュアルです。
  • Arduino Core for the ESP32 – ESP32 特有のドキュメントは見つけられなかったのですが、component/arduino の中にソースといくつかの example がありますのでなんとかなるかと思います。 🙂
  • M5Stack Arduino API – M5Stack 特有の LCD やスピーカーなど拡張された便利な API の記載があります。

ESP32 はドキュメントがしっかりしていて使いやすいですね。

てなわけで hello happy coding!


Windows でビルドの速度が遅い件

当初 Windows 上の WSL(Windows Service for Linux)を使い Linux 用のツールチェインを使っていたのですが、コンパイルがちょっと待てないくらい遅いので普通の Windows 向けツールチェインを使うように変更しました。

また、WSL から Windows のツールチェインに変更してもどうにも Linux と比較してコンパイルが遅いので、さくさく開発を求める方は生か仮想の Linux 上で作業するといいかもです。なお、現在開発版(v4.0)の esp-idf には新 Windows のツールチェインが提供されており、将来的にコンパイル速度は恐らく今後改善されるのではないかと思います。

現時点、本記事では以下の文書を参考に make 時に -j4 オプションをつけて CPU コアを活用してコンパイル時間を改善した手順としました。(8コアの方は -j8 にしてください) Windows Defender をお使いの場合、プロジェクトフォルダを監視から外すのも有効なようです。

[Advice] Boost ESP-IDF Compile time on Windows 10

I have been building ESP-IDF projects for a while now, and as many of you I think have noticed, compile time on Windows 10 is VERY slow.

I just want to share some steps i have done to boost ESP-IDF project compile time on Windows 10.

関連

コメントを残す