カスタムボードを ESP-IDF 6 に移行する:上流の移行コミットから学ぶ
上流のファームウェアは、v2.4.0 の 3e78cd7 で ESP-IDF 6.0 に移行し、v2.5.0 で ESP-IDF 5.x のサポートを削除しました。自分のボードのディレクトリを保守している場合、アップグレード後の典型的な症状はビルドエラーです。ヘッダーが見つからない、ドライバーのコンポーネントが足りない、構造体の初期化子がコンパイルできなくなった、といったものです。
上流には、移行専用のドキュメントがありません。この記事がやることは 1 つだけです。Espressif 公式の 6.0 移行ガイドと、上流の移行コミットでの実際の変更を突き合わせ、カスタムボードがまず確認すべき箇所を挙げます。各項目は、この 2 つの出典のどちらかに遡れます。ボードがどの周辺機器を使っているかは、あなたにしか分かりません。ですから、これはチェックリストであり、コンパイラのエラーの代わりにはなりません。
3e78cd7 は、多数のボードにわたって 119 ファイル(1,379 行の追加、654 行の削除)を変更しています。以下の例は、そのうちのいくつかのボードからのものです。ディレクトリ名は、そのコミット時点のパスです。v2.5.2 では、main/boards はベンダーごとにまとめられています。例:espressif/esp-hi、alientek/atk-dnesp32s3-box2-wifi。1. まず環境を正しく整える
- ESP-IDF v6.0.1 以降、できれば
release/v6.1ブランチをインストールします。v6.1のリリースタグは避けてください(ESP32-C3 で Wi-Fi の初期化に失敗するという報告があります。issue #2344 を参照)。 - SDK を切り替えたら、
git submodule update --init --recursiveを実行し、export.shを読み込み直して、idf.py fullcleanを実行します。 idf.py --versionで、ターミナルが新しいバージョンを読み込んだことを確認します。
詳しい手順は ESP-IDF のセットアップにあります。環境が間違っていると、ほかのエラーはすべてノイズになります。まずこれを除外してください。
2. チェックリスト
1. ドライバーコンポーネントの依存関係を明示する
公式ガイドによると、従来の driver コンポーネントは、esp_driver_i2s、esp_driver_spi、esp_driver_uart、esp_driver_ledc などのドライバーコンポーネントへの公開依存を持たなくなりました。driver への依存を外して、対応する esp_driver_xxx コンポーネントを追加することが推奨されています。
上流の main/CMakeLists.txt は、PRIV_REQUIRES に esp_driver_gpio、esp_driver_uart、esp_driver_spi、esp_driver_i2c、esp_driver_i2s、esp_driver_ledc などを挙げています。一部のボードだけが必要とするコンポーネントは MAIN_PRIV_REQUIRES_EXTRA に入れます。例えば ESP32-P4 Function EV Board は esp_driver_sdmmc と sdmmc を追加しています。
カスタムボードが新しい周辺機器のドライバーを使うなら、同じやり方でプロジェクトに依存関係を追加してください。
2. FreeRTOS のヘッダーを自分でインクルードする
公式ガイドによると、6.0 以降、公開されているドライバーのヘッダーは FreeRTOS のヘッダーをインクルードしなくなりました。暗黙のインクルードに頼っていたコードは、自分で追加する必要があります。移行コミットでは、3 か所にこれを追加しています。
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>3. 旧ドライバーのヘッダーは削除済み、またはサポート終了
公式ガイドは、次の旧ドライバーのヘッダーを、6.0 で完全に削除されたものとして挙げています:driver/adc.h、driver/dac.h、driver/i2s.h、driver/timer.h、driver/pcnt.h、driver/rmt.h、driver/mcpwm.h、driver/sigmadelta.h。旧 I2C ドライバーの driver/i2c.h は 6.0 でサポート終了とされ、7.0 で削除される予定です。ガイドは driver/i2c_master.h を推奨しています。
移行コミットが行ったこと:
| 旧 | 新 |
|---|---|
#include <driver/adc.h>(2 か所で削除) | #include <esp_adc/adc_oneshot.h>(1 か所で置き換え、もう 1 か所は既に記載済み) |
#include <driver/i2c.h> | #include <driver/i2c_master.h> |
ボードのディレクトリにある旧ヘッダーを見つけるには、次のコマンドを使います。
# Run from the firmware root; every hit is a migration candidate
rg -n 'driver/(adc|dac|i2s|timer|pcnt|mcpwm|rmt|sigmadelta|temp_sensor)\.h|driver/i2c\.h' main/boards/<your-board>4. LCD ドライバーの GPIO の型と初期化
公式ガイドによると、LCD ドライバーでの GPIO 番号の型は、int から型安全な gpio_num_t に変わりました。移行コミットでの対応する変更は、リセットピンの -1 を GPIO_NUM_NC に置き換えるものです。
// Before
panel_config.reset_gpio_num = -1;
// After
panel_config.reset_gpio_num = GPIO_NUM_NC;同じコミットは、bread-compact-wifi の SSD1306 の初期化にも 2 つの変更を加えています。自分の I2C ディスプレイのコードと比べてみてください。
- パネル IO を作る呼び出しが、
esp_lcd_new_panel_io_i2c_v2(...)からesp_lcd_new_panel_io_i2c(...)に変わりました。 esp_lcd_panel_io_i2c_config_tで、.scl_speed_hzが.dev_addrの後ろに上がり、.on_color_trans_doneと.user_ctxが.lcd_param_bitsの後ろに移りました。C++ の指示付き初期化子は、構造体の宣言順に従わなければならず、そうでないとコンパイラがエラーを報告します。
また、atoms3-echo-base は、パネル設定で rgb_endian = LCD_RGB_ENDIAN_BGR を rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR に変更しています。
5. スリープからの復帰要因はビットマスク API を使う
main/boards/common/sleep_timer.cc で、移行コミットは esp_sleep_get_wakeup_cause() を esp_sleep_get_wakeup_causes() に置き換えました。新しい呼び出しは、複数の復帰要因を同時に表せるビットマスクを返します。そのためタイマーの判定はビットテストになり、32 ビットの値は PRIx32 で出力します(<inttypes.h> をインクルードします)。
auto wakeup_causes = esp_sleep_get_wakeup_causes();
ESP_LOGI(TAG, "Wake up from light sleep, wakeup_causes: 0x%" PRIx32, wakeup_causes);
if (!(wakeup_causes & (1UL << ESP_SLEEP_WAKEUP_TIMER))) {
break;
}ボードが独自のスリープ処理を実装しているなら、これと見比べてください。
6. 連続 ADC:同じタスクで開始と停止を行う
esp-hi と esp-sensairshuttle の adc_pdm_audio_codec.cc で、移行コミットは Start() から EnableInput(true) を削除し、コメントを追加しました。入力は AudioService::AudioInputTask が遅延して開く、というものです。ESP-IDF の ADC 連続ドライバーは、開始と停止を同じタスクで実行する必要があるためです。カスタムの ADC/PDM のオーディオコーデックは、この制約を守ってください。
7. コンポーネントのバージョンが先に進む
main/idf_component.yml で、移行コミットはいくつかのコンポーネントをメジャーバージョンごと引き上げました。例:
| コンポーネント | 旧 | 新 |
|---|---|---|
espressif/esp_lcd_ili9341 | ==1.2.0 | ^2.0.2 |
espressif/esp_lcd_st77916 | ^1.0.1 | ^2.0.2 |
espressif/esp_lcd_axs15231b | ^1.0.0 | ^2.1.0 |
espressif/esp_lcd_st7701 | ^1.1.4 | ^2.0.2 |
espressif/esp_video | ==1.3.1 | ^2.0.1 |
ボードがこれらのディスプレイドライバーに依存しているなら、メジャーバージョンの更新で API が変わっているかもしれません。あわせて確認してください。
8. オーディオのクロック設定はボードごとに異なる
移行の途中で、いくつかのオーディオボードはクロック設定も調整されました。例えば atk-dnesp32s3-box2 は、オーディオのサンプルレートを 16000 Hz から 24000 Hz に変更し、AUDIO_CODEC_USE_MCLK true を追加しました。のちのコミット c0fe42a で、オーディオコーデック全体の I2S クロック設定が統一されました。アップグレード後にノイズが出る、または音が出ない場合は、config.h とコーデックの実装を、似たボードと比べてください。
9. C++ の標準が固定されている
上流の main/CMakeLists.txt のコメントによると、ESP-IDF 6 は、より新しい C++ の方言を既定にすることがあります。そこでプロジェクトは、自分の C++ を -std=gnu++23 に固定し、main/ が IDF の既定に依存しないようにしています。ボードのコードもこの標準でビルドされます。
3. おすすめの順序
- 環境を整え、
idf.py fullcleanを実行します。 - 上の
rgコマンドを実行し、旧ヘッダーを片付けます。 - FreeRTOS のヘッダーと
esp_driver_xxxの依存関係を追加します。 - 4〜6 の項を参考に、LCD、スリープ、ADC のコードを見直します。
python scripts/build.py <ボードのディレクトリ>でビルドし、エラーを 1 つずつ直します。- ビルドが通ったら、書き込んで、表示、音声、ウェイクワードを確認します。
ボードのディレクトリ構成、config.json、build.py はカスタムボードガイドを参照してください。全体の変更は v2.5 解説を参照してください。
出典
- Espressif のドキュメント:Migration from 5.5 to 6.0 の Peripherals の節。
- 上流のコミット
3e78cd7(v2.4.0)、c0fe42a、およびv2.5.2タグのmain/CMakeLists.txt、main/idf_component.yml、main/boards/common/sleep_timer.cc。 - 2026-10-23 に確認。訂正は [email protected] までお送りください。