Ubuntu上で複数の開発環境を使用しているのですが、環境設定が複雑になってきたため、各環境を"Docker"で個別に構築しています。
この記事ではESP-IDFをDockerコンテナで動かすために実行した内容を 覚書 として関係するリンクと内容を簡単にまとめます。
苦労したポイントは、コンテナからUSBデバイスのシリアルポートにアクセスする部分で コンテナ起動時の引数とコンテナ内でのシリアルポートのアクセス権の設定 です。
開発環境
- ホスト: Ubuntu 22.04.5 LTS
- Docker: 28.0.1, build 068a01e
Dockerのインストール
以下の記事を参考にDocker Engineをインストールします。
事前準備
必要なパッケージをインストールします。
$ sudo apt update
$ sudo apt install ca-certificates curl gnupg
aptリポジトリを追加します。
$ sudo install -m 0755 -d /etc/apt/keyrings
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
$ sudo chmod a+r /etc/apt/keyrings/docker.asc
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
dockerグループを作成し、ユーザーをグループに追加します。これによってroot以外のユーザーもDockerを実行できるようになります。
$ sudo groupadd docker
$ sudo usermod -aG docker "ユーザー名"
Docker Engine のインストール
以下のコマンドでDocker Engineをインストールします。
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
インストールされたことを確認しておきます。
$ docker --version
Dockerコンテナの作成
Dockerイメージの取得
Docker Hubのubuntuリポジトリからコンテナイメージを取得します。
今回は最新版ではなく22.04を使用しました。
$ docker pull ubuntu:22.04
Dockerイメージが取得されたことを確認します。
$ docker images
正常に取得されていたら、以下のように表示されます。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 22.04 a24be041d957 6 weeks ago 77.9MB
コンテナの作成
取得したイメージ(ubuntu:22.04)からコンテナを作成します。
$ docker run -it ubuntu:22.04
以下のようにrootでログインした状態のコンテナが自動で起動します。
root@xxx:/#
コンテナの初期設定
コンテナに基本的なツールをインストールします。
root@xxx:/# apt update
root@xxx:/# apt install sudo
root@xxx:/# sudo apt install vim
usbutilsとnet-toolsもインストールしておきます。
root@xxx:/# sudo apt install usbutils
root@xxx:/# sudo apt install net-tools
ツールを実行するためにユーザを追加しておきます。
途中でパスワード設定が要求されますので設定しておきます。
root@xxx:/# adduser "ユーザー名"
Adding user `user' ...
Adding new group `user' (1000) ...
Adding new user `user' (1000) with group `user' ...
Creating home directory `/home/user' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for user
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []: Home Phone []:
Other []:
Is the information correct? [Y/n] y
sudoグループに追加します。
root@xxx:/# gpasswd -a "ユーザー名" sudo
ここまで設定したらコンテナを終了します。
root@xxx:/# exit
初期設定済のDockerイメージの生成
コンテナの稼働状況を確認します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cf86377b941 ubuntu:22.04 "/bin/bash" 32 minutes ago Exited (0) About a minute ago trusting_chaum
設定済のコンテナからDockerイメージを生成します。(少し時間がかかります)
$ docker commit trusting_chaum ubuntu_init:22.04
イメージが生成されたことを確認します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu_init 22.04 8840e33bb613 About a minute ago 201MB
ubuntu 22.04 a24be041d957 6 weeks ago 77.9MB
初期設定済のDockerイメージからESP-IDF用のコンテナを起動
使用するデバイスの接続状況を確認
使用するデバイスをPCに接続し、ホストOSでデバイスの接続情報を確認します。
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 8087:0a2a Intel Corp. Bluetooth wireless interface
Bus 001 Device 002: ID 303a:1001 Espressif USB JTAG/serial debug unit
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
デバイスが認識されていたら、シリアルポートの名称を確認します。
$ sudo dmesg | grep tty
[ 0.215010] printk: legacy console [tty0] enabled
[ 5.742179] cdc_acm 1-4:1.0: ttyACM0: USB ACM device
この例では、"ttyACM0"という名称で認識されています。
Dockerコンテナにデバイスをマウントして起動
Dockerコンテナをデバイスをマウントした状態で、先程追加したユーザー名(user)でログインして起動します。
$ docker run -it --user user --device=/dev/ttyACM0 -v /dev/ttyACM0:/dev/ttyACM0 --name esp-idf ubuntu_init:22.04
コンテナで"ttyACM0"が認識されているのを確認します。
user@xxx:/$ ls /dev/tty*
user@7b260fb6bd53:/$ ls -la /dev/tty*
crw-rw-rw- 1 root root 5, 0 Mar 16 00:16 /dev/tty
crw-rw---- 1 root dialout 166, 0 Mar 15 22:39 /dev/ttyACM0
ユーザーのhomeに移動します。
user@xxx:/$ cd
ESP-IDFのツールチェーンのセットアップ
下記の手順に従い、ESP-IDFのツールチェーンをセットアップしていきます。
必要なパッケージを導入する
ESP-IDFを使用してコンパイルするために、次のコマンドでパッケージを導入します。
user@xxx:~$ sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
ESP-IDFを取得する
ESP-IDFをインストールするディレクトリに移動し、次の手順でリポジトリをクローンします。今回は以下の設定で実行しました。
- インストールディレクトリ: ~/esp/
- バージョン: v5.4 (2025/03/16時点の最新版)
ESP-IDFのバージョンについてはこちらを参照してください。
user@xxx:~$ mkdir -p ~/esp
user@xxx:~$ cd ~/esp
user@xxx:~/esp$ git clone -b v5.4 --recursive https://github.com/espressif/esp-idf.git
ESP-IDFのクローンは ~/esp/esp-idf にダウンロードされます。
必要なツールを設定する
ESP32をサポートするプロジェクトでは、ESP-IDFの他に、コンパイラ、デバッガー、Python パッケージなど、ESP-IDFで使用されるツールもインストールする必要があります。
以下のコマンドを参考にターゲットとするチップをリストしてスクリプトを実行します。
必要なツールはLinux 上のユーザーホームディレクトリ( ~/.espressif )にインストールされます。
user@xxx:~/esp$ cd ~/esp/esp-idf
user@xxx:~/esp/esp-idf$ ./install.sh esp32,esp32s3
サポートされているすべてのターゲット用のツールをインストールするには、次のコマンドを実行します。
user@xxx:~/esp$ cd ~/esp/esp-idf
user@xxx:~/esp/esp-idf$ ./install.sh all
環境変数を設定する
ツールをコマンドラインから使用するためには、いくつかの環境変数を設定する必要があります。ESP-IDFには、それを実行するスクリプトが用意されていますので、次のコマンドを実行します。
先頭のドットとパスの間のスペースに注意してください。
user@xxx:~$ . ~/esp/esp-idf/export.sh
以下のメッセージが表示されたら、設定完了です。
Checking "python3" ...
Python 3.10.12
"python3" has been detected
Activating ESP-IDF 5.4
* Checking python version ... 3.10.12
* Checking python dependencies ... OK
* Deactivating the current ESP-IDF environment (if any) ... OK
* Establishing a new ESP-IDF environment ... OK
* Identifying shell ... bash
* Detecting outdated tools in system ... OK - no outdated tools found
* Shell completion ... Autocompletion code generated
Done! You can now compile ESP-IDF projects.
Go to the project directory and run:
idf.py build
サンプルプロジェクトで動作確認をする
ESP-IDFのプロジェクトを開始する準備が完了しましたので、実際にサンプルプロジェクト(hello_world")をビルドしてターゲット上で実行してみます。
サンプルプロジェクトをコピーする
ESP-IDFのexamplesディレクトリからhello_worldプロジェクトをコピーします。
user@xxx:~$ cd ~/esp
user@xxx:~/esp$ cp -r ~/esp/esp-idf/examples/get-started/hello_world ./
プロジェクトを構成する
hello_worldディレクトリに移動し ESP32S3 をターゲットとして設定します。
user@xxx:~$ cd ~/esp/hello_world
user@xxx:~/esp/hello_world$ idf.py set-target esp32s3
プロジェクト構成ユーティリティ(menuconfig)を実行します。
user@xxx:~/esp/hello_world$ idf.py menuconfig
この手順が正しく実行された場合、次のメニューが表示されます。
このメニューを使用して、Wi-Fi ネットワーク名とパスワード、プロセッサ速度、フラッシュの容量などのプロジェクト固有の変数を設定します。今回のプロジェクト(hello_world)はデフォルト構成で実行しますので、デフォルトのまま[Q]で終了します。
プロジェクトをビルドする
次のコマンドを実行してプロジェクトをビルドします。このコマンドは、アプリケーションとすべてのESP-IDFコンポーネントをコンパイルし、ブートローダ、パーティション テーブル、およびアプリケーションバイナリを生成します。
user@xxx:~/esp/hello_world$ idf.py build
"Project build complete."が表示されたら、ビルド完了です。エラーがなければ、ファームウェアのバイナリ(.bin)ファイルが生成されてビルドが終了します。
Executing action: all (aliases: build)
Running ninja in directory /home/***/esp/hello_world/build
Executing "ninja all"...
[0/1] Re-running CMake...
~中略~
Project build complete. To flash, run:
idf.py flash
or
idf.py -p PORT flash
or
python -m esptool --chip esp32s3 -b 460800 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_size 2MB --flash_freq 80m 0x0 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x10000 build/hello_world.bin
or from the "/home/tomorrow56/esp/hello_world/build" directory
python -m esptool --chip esp32s3 -b 460800 --before default_reset --after hard_reset write_flash "@flash_args"
デバイスにフラッシュする
デバイスに書き込む前に"/dev/ttyACM0"のアクセス権を"666"に修正します。
user@xxx:~/esp/hello_world$ sudo chmod 666 /dev/ttyACM0
ESP32S3用にビルドしたバイナリを次のコマンドを実行してデバイスのポート(/dev/ttyACM0)に書き込みます。
user@xxx:~/esp/hello_world$ idf.py -p /dev/ttyACM0 flash
問題がなければ、ボードが再起動し hello_world アプリケーションが起動します。
Executing action: flash
Running ninja in directory /home/tomorrow56/esp/hello_world/build
Executing "ninja flash"...
~中略~
Compressed 3072 bytes to 103...
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 559.3 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
Done
シリアル出力をモニターする
hello_world が実際に実行されているかどうかを確認するために、IDFモニターアプリケーションを起動します。
user@xxx:~/esp/hello_world$ idf.py -p /dev/ttyACM0 monitor
ログに"Hello world!"と表示されていれば問題なくプログラムが動いています。
IDFモニターを終了するには、ショートカット(Ctrl+])を使用します。
Executing action: monitor
Running idf_monitor in directory /home/tomorrow56/esp/hello_world
Executing "/home/tomorrow56/.espressif/python_env/idf5.4_py3.10_env/bin/python /home/tomorrow56/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyACM0 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 --revision 0 /home/tomorrow56/esp/hello_world/build/hello_world.elf -m '/home/tomorrow56/.espressif/python_env/idf5.4_py3.10_env/bin/python' '/home/tomorrow56/esp/esp-idf/tools/idf.py' '-p' '/dev/ttyACM0'"...
--- esp-idf-monitor 1.5.0 on /dev/ttyACM0 115200
~中略~
Hello world!
This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision v0.2, 2MB external flash
Minimum free heap size: 390340 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
無事に動作したら、次回開始時に環境設定を読み込むように".bashrc"に以下を追記しておきます。
. ~/esp/esp-idf/export.sh
ESP-IDF設定済のDockerイメージを生成
無事に動作したら、ESP-IDF設定済のコンテナからDockerイメージを生成しておきます。
まず、Dockerコンテナから抜けます。
user@xxx:~/esp/hello_world$ exit
コンテナの稼働状況を確認します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
def595ae9ac0 esp-idf-2:22.04 "/bin/bash" 30 minutes ago Exited (0) About a minute ago esp-idf
コンテナが稼働中の場合は停止します。
$ docker stop esp-idf
ESP-IDFが設定済のコンテナからDockerイメージを生成します。(少し時間がかかります)
$ docker commit esp-idf esp-idf:22.04
イメージが生成されたことを確認します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
esp-idf 22.04 e3a774de9044 5 hours ago 7.21GB
ubuntu_init 22.04 8840e33bb613 About a minute ago 201MB
ubuntu 22.04 a24be041d957 6 weeks ago 77.9MB
作業は以上になります。お疲れ様でした。
その他の操作
フラッシュ消去
フラッシュを消去することも可能です。フラッシュ メモリ全体を消去するには、次のコマンドを実行します。
idf.py -p <PORT> erase-flash
OTA データが存在する場合は、消去には次のコマンドを実行します。
idf.py -p <PORT> erase-otadata
参考情報(リンク)
Build System
idf.pyのオプションの説明があります。
m5stack のソフトウェアを esp-idf 環境で開発して動かす
5GFXライブラリを導入しサンプルを動かす方法が説明されています。