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

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

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

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

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

WSL から Windows のツールチェインに変更してもどうにも Linux と比較してコンパイルが遅いので、さくさく開発を求める方は生か仮想の Linux 上で作業するといいかもです。なお、現在開発版(v3.2)の esp-idf にはプレビューとして CMake ベースのWindows のツールチェインが提供されており、将来的にネイティブの cmake/gcc 構成になるようなのでコンパイル速度は恐らく今後改善されるのではないかと思います。

本記事では以下の文書を参考に 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.

ESP32/M5Stack の開発系の構成

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

  • xtensa-esp32 – ツールチェイン(gccクロスコンパイラ+転送ツール等) Windows/Linux/macOS 用に分かれています。
  • esp-idf – ESP32 用のフレームワーク(ライブラリ)
  • 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 開発で必須なのは上の2つです。

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

ツールチェインの導入

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

Windows 上の任意の場所に開発系の作業フォルダー(ここでは C:\develop\esp)を作成しダウンロードしたツールチェインの .zip を展開します。執筆時点では esp32_win32_msys2_environment_and_toolchain-20180110.zip でした。

Toolchain Setup

展開できたら 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 にあり事前にパスが通っています。

esp-idf の導入

引き続き mingw シェル上で次のコマンドから esp-idf を導入します。(こちらも最新情報は次のリンクを確認してください)

Get ESP-IDF

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

git clone で指定している v3.1.3 が esp-idf のバージョンになります。ディレクトリ esp-idf が作成され esp-idf が格納されます。

次にソースファイルの Makefile で指定されている IDF_PATH 環境変数に上記で得られた 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

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

Arduino Core テンプレートのコピー

ESP32 で Arduino Core を使う場合は、次のコマンドでプロジェクトに Arduino Core コンポーネントを追加することができます。上記で配置した ESP32 テンプレートプロジェクトに 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 のバージョンになります。もし後述の make が通らないようであれば esp-idf と Arduino Core の依存バージョンが不整合していますので最新の情報を確認してみてください。

この手順では esp-idf v3.1.3 と Arduino Core 1.0.0 の組み合わせを使っています。 Arduino Core 1.0.1 は esp-idf v3.2(現在rc) に依存するため v3.1.3 だとコンパイルエラーとなります。将来の手順は esp-idf v3.2 と Arduino Core 1.0.1 以降の組み合わせになるでしょう。

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

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

プログラムの転送

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

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 で開きます。(ここでは先ほどつくった C:\develop\esp\msys32\home\[ユーザ名]\esp\hello_m5stack フォルダを開いています)

プロジェクトフォルダーに上のように .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 を新規作成し次のように設定します。

{
    "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!

このエントリーをはてなブックマークに追加

コメントを残す

メールアドレスが公開されることはありません。