自訂開發板遷移到 ESP-IDF 6:從上游遷移提交學到的改法
上游韌體在 v2.4.0 透過 3e78cd7 遷移到 ESP-IDF 6.0,v2.5.0 起移除了 ESP-IDF 5.x 支援。如果你維護過自己的開發板目錄,升級後最常見的現象就是編譯報錯:找不到標頭檔、找不到驅動元件,或者結構體初始化不透過。
上游沒有單獨的“遷移指南”文件。本文只做一件事:把樂鑫官方的 6.0 遷移指南和上游這次遷移提交裡的真實改動對照起來,列出自訂開發板最該檢查的位置。每一條都能在這兩份資料裡找到出處;你的板子用了什麼外設,只有你自己最清楚,所以請把它當作檢查清單,而不是替代編譯器報錯。
3e78cd7 改動了 119 個檔案(新增 1379 行、刪除 654 行),涉及大量板卡。下面的例子取自其中幾個板卡,目錄名取自遷移提交當時的路徑;v2.5.2 中 main/boards 已按廠商分組,例如 espressif/esp-hi、alientek/atk-dnesp32s3-box2-wifi。一、先把環境換對
- 安裝 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確認當前終端載入的是新版本。
完整步驟見開發環境搭建。環境不對時,後面的報錯都是噪聲,先排除這一項。
二、檢查清單
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 標為終止支援(EOL),計劃在 7.0 移除,官方建議改用 driver/i2c_master.h。
遷移提交裡對應的改動:
| 舊寫法 | 新寫法 |
|---|---|
#include <driver/adc.h>(兩處刪除) | #include <esp_adc/adc_oneshot.h>(其中一處改為該標頭檔,另一處已有) |
#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 初始化裡還做了兩處改動,可以對照自己的 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. 睡眠喚醒原因改用位元遮罩介面
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. 編譯標準已固定
上游 main/CMakeLists.txt 在註解裡寫明:ESP-IDF 6 的 C++ 預設標準可能更新,所以專案自己的 C++ 固定為 -std=gnu++23,避免 main/ 依賴 IDF 的預設值。你的板級程式碼同樣按這個標準編譯。
三、一個推薦的遷移順序
- 換好環境並
idf.py fullclean; - 跑上面的
rg命令,處理舊標頭檔; - 補 FreeRTOS 標頭檔與
esp_driver_xxx依賴; - 對照第 4~6 節檢查 LCD、睡眠和 ADC 相關程式碼;
- 用
python scripts/build.py <你的板子目錄名>編譯,按報錯逐項處理; - 編譯透過後再燒錄驗證顯示、音訊和喚醒。
板卡目錄結構、config.json 與 build.py 的用法見自訂開發板指南;韌體整體變化見v2.5 解讀。
對照來源
- 樂鑫官方文件:從 5.5 遷移到 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]。