Перенос пользовательской платы на ESP-IDF 6: уроки коммита upstream с миграцией
Upstream-прошивка перешла на ESP-IDF 6.0 в v2.4.0 коммитом 3e78cd7, а в v2.5.0 поддержка ESP-IDF 5.x была удалена. Если вы поддерживаете собственный каталог платы, типичный симптом после обновления — ошибка сборки: не находится заголовок, не хватает компонента драйвера или перестала компилироваться инициализация структуры.
Отдельного документа по миграции у upstream нет. Эта статья делает одно: сопоставляет официальное руководство Espressif по миграции на 6.0 с реальными изменениями в коммите upstream с миграцией и перечисляет места, которые пользовательской плате стоит проверить в первую очередь. Каждый пункт восходит к одному из этих двух источников. Какие периферийные устройства использует ваша плата, знаете только вы, поэтому считайте это списком проверок, а не заменой сообщений компилятора.
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(сообщалось о сбоях инициализации Wi-Fi на ESP32-C3, см. 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 upstream в 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 помечен как end-of-life, а удалить его планируют в 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. Тип GPIO и инициализация в драйвере LCD
Официальное руководство сообщает, что тип номера GPIO в драйвере LCD изменился с int на типобезопасный gpio_num_t. Соответствующее изменение в коммите с миграцией заменяет -1 для вывода сброса на GPIO_NUM_NC:
// Before
panel_config.reset_gpio_num = -1;
// After
panel_config.reset_gpio_num = GPIO_NUM_NC;В инициализации SSD1306 платы bread-compact-wifi тот же коммит внёс ещё два изменения, которые можно сравнить с вашим кодом дисплея на I2C:
- вызов создания panel 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. Назначенные инициализаторы (designated initializers) 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: запуск и остановка в одной задаче
В adc_pdm_audio_codec.cc у esp-hi и esp-sensairshuttle коммит с миграцией убрал EnableInput(true) из Start() и добавил комментарий: вход открывается лениво в AudioService::AudioInputTask, потому что драйвер непрерывного ADC в ESP-IDF требует, чтобы запуск и остановка выполнялись в одной задаче. Пользовательские аудиокодеки на 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 Гц на 24000 Гц и добавила AUDIO_CODEC_USE_MCLK true. Более поздний коммит c0fe42a унифицировал конфигурацию тактов I2S у аудиокодеков. Если после обновления на вашей плате шум или нет звука, сравните её config.h и реализацию кодека с похожей платой.
9. Стандарт C++ зафиксирован
Комментарий в main/CMakeLists.txt upstream объясняет, что ESP-IDF 6 может по умолчанию использовать более новый диалект C++, поэтому проект фиксирует свой C++ на -std=gnu++23, чтобы main/ не зависел от значения по умолчанию в IDF. Код вашей платы тоже собирается по этому стандарту.
3. Рекомендуемый порядок
- Приведите окружение в порядок и выполните
idf.py fullclean. - Выполните команду
rgвыше и разберитесь с прежними заголовками. - Добавьте заголовки FreeRTOS и зависимости
esp_driver_xxx. - Просмотрите код LCD, сна и ADC по пунктам 4–6.
- Соберите через
python scripts/build.py <каталог-вашей-платы>и исправляйте ошибки по одной. - Когда сборка пройдёт, прошейте плату и проверьте дисплей, звук и слово пробуждения.
О структуре каталога платы, config.json и build.py см. Руководство по пользовательским платам. Об общих изменениях — обзор v2.5.
Источники
- Документация Espressif: Migration from 5.5 to 6.0, раздел Peripherals.
- Коммит upstream
3e78cd7(v2.4.0),c0fe42a, а такжеmain/CMakeLists.txt,main/idf_component.yml,main/boards/common/sleep_timer.ccв тегеv2.5.2. - Проверено 2026-10-23. Исправления присылайте на [email protected].