自定义开发板迁移到 ESP-IDF 6:从上游迁移提交学到的改法

自定义开发板迁移到 ESP-IDF 6:从上游迁移提交学到的改法

October 23, 2026

上游固件在 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。

一、先把环境换对

  1. 安装 ESP-IDF v6.0.1 或更高版本,推荐 release/v6.1 分支;避免使用 v6.1 发布标签(ESP32-C3 上有 Wi-Fi 初始化失败的报告,见 issue #2344)。
  2. 切换 SDK 后执行 git submodule update --init --recursive,重新加载 export.sh,再执行 idf.py fullclean。
  3. 用 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 的默认值。你的板级代码同样按这个标准编译。

三、一个推荐的迁移顺序

  1. 换好环境并 idf.py fullclean;
  2. 跑上面的 rg 命令,处理旧头文件;
  3. 补 FreeRTOS 头文件与 esp_driver_xxx 依赖;
  4. 对照第 4~6 节检查 LCD、睡眠和 ADC 相关代码;
  5. 用 python scripts/build.py <你的板子目录名> 编译,按报错逐项处理;
  6. 编译通过后再烧录验证显示、音频和唤醒。

板卡目录结构、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]。