Основная проблема в том, что в исходной собранной библиотеке arduino-esp32 для PlatformIO функции сбора статистики (vTaskGetRunTimeStats
/ vTaskList
) отключены. Библиотека используется как есть, ссылки на гайды по сборке своих библиотек устарели (404), а актуальных доступных всем инструкций просто нет. К тому же issues по добавлению этих функций также не рассматривают, т.к. они связаны с использованием сторонней библиотеки.
Чтобы добавить эти функции - нужно пересобрать библиотеку с измененными параметрами. В качестве OS используем Ubuntu (Windows - пользователи могут поднять виртуалку в WSL).
Esp32 arduino lib builder
Инструкция установке билдера и сборке есть на официальном сайте. Устанавливаем зависимости:
sudo apt-get install git wget curl libssl-dev libncurses-dev flex bison gperf cmake ninja-build ccache jq python3
sudo pip install --upgrade pip
pip install --user setuptools pyserial click cryptography future pyparsing pyelftools
Можно дальше по инструкции клонировать репозиторий и запустить сборку. Скачивание всех зависимостей и сборка занимают примерно час.
А потом результаты сборки можете ... удалить, потому что версии самого билдера и всех используемых библиотек отличаются и использовать их в PlatformIO не получится.
![И засуньте себе это в зад](https://habrastorage.org/getpro/habr/upload_files/d20/ab2/aa7/d20ab2aa746bd1fe812514de4e197495.png)
Нам нужны конкретные версии конкретных пакетов, билдер из коробки такой возможности не предоставляет, поэтому придется ему помочь. Актуальные версии пакетов, которые используются в PlatformIO, можно посмотреть в ~/.platformio/packages/framework-arduinoespressif32/tools/sdk/version.txt
, у меня файл выглядит так:
esp-idf: v4.4.7 38eeba213a
arduino: idf-38eeba213a d75795f5
esp-dl: master 0632d24
esp-rainmaker: master d8e9345
esp32-camera: master f0bb429
esp_littlefs: master 41873c2
espressif__esp-dsp: master 9b4a8b4
tinyusb: master a0e5626bc
Каким-то чудом по хешу коммита версии одной из библиотек в PlatformIO удалось найти статью на японском (!), которая описывает, что действительно нужно сделать для пересборки библиотеки. Билдер мы ставили не зря, но вот дальше начинаются приключения - каждую из этих библиотек придется установить вручную.
Для начала все же клонируем билдер и переключим версию:
git clone https://github.com/espressif/esp32-arduino-lib-builder
cd esp32-arduino-lib-builder
git switch release/v4.4
Далее необходимо зафиксировать каждую версию библиотеки, поэтому нужно закомментировать в билдере автоматическое обновление компонентов (build.sh:84-87
):
# echo "* Installing/Updating ESP-IDF and all components..."
# update components from git
# ./tools/update-components.sh
# if [ $? -ne 0 ]; then exit 1; fi
Теперь придется вручную загрузить все компоненты, включая ESP-IDF и ядро Arduino для ESP32 .
TLDR установка всех зависимостей в одну строку
git clone -b v4.4.7 --recursive https://github.com/espressif/esp-idf.git && git -C ./esp-idf/ reset --hard 38eeba213a && git clone -b 2.0.17 --recursive https://github.com/espressif/arduino-esp32 ./components/arduino && git -C ./components/arduino reset --hard d75795f5 && git clone --recursive https://github.com/espressif/esp32-camera ./components/esp32-camera && git -C ./components/esp32-camera reset --hard f0bb429 && git clone --recursive https://github.com/espressif/esp-dl.git ./components/esp-dl && git -C ./components/esp-dl reset --hard 0632d24 && git clone --recursive https://github.com/joltwallet/esp_littlefs.git ./components/esp_littlefs && git -C ./components/esp_littlefs reset --hard 41873c2 && git -C ./components/esp_littlefs submodule update --init --recursive && git clone --recursive https://github.com/espressif/esp-rainmaker.git ./components/esp-rainmaker && git -C ./components/esp-rainmaker reset --hard d8e9345 && git -C ./components/esp-rainmaker submodule update --init --recursive && git clone --recursive https://github.com/espressif/esp-dsp.git ./components/espressif__esp-dsp && git -C ./components/espressif__esp-dsp reset --hard 9b4a8b4 && git clone --recursive https://github.com/hathach/tinyusb.git ./components/arduino_tinyusb/tinyusb && git -C ./components/arduino_tinyusb/tinyusb reset --hard a0e5626bc
Ниже разбивка по библиотекам и командам.
esp-idf
git clone -b v4.4.7 --recursive https://github.com/espressif/esp-idf.git
git -C ./esp-idf/ reset --hard 38eeba213a
arduino-esp32
git clone -b 2.0.17 --recursive https://github.com/espressif/arduino-esp32 ./components/arduino
git -C ./components/arduino reset --hard d75795f5
esp32-camera
git clone --recursive https://github.com/espressif/esp32-camera ./components/esp32-camera
git -C ./components/esp32-camera reset --hard f0bb429
esp-dl
git clone --recursive https://github.com/espressif/esp-dl.git ./components/esp-dl
git -C ./components/esp-dl reset --hard 0632d24
esp_littlefs
git clone --recursive https://github.com/joltwallet/esp_littlefs.git ./components/esp_littlefs
git -C ./components/esp_littlefs reset --hard 41873c2
git -C ./components/esp_littlefs submodule update --init --recursive
esp-rainmaker
git clone --recursive https://github.com/espressif/esp-rainmaker.git ./components/esp-rainmaker
git -C ./components/esp-rainmaker reset --hard d8e9345
git -C ./components/esp-rainmaker submodule update --init --recursive
espressif__esp-dsp
git clone --recursive https://github.com/espressif/esp-dsp.git ./components/espressif__esp-dsp
git -C ./components/espressif__esp-dsp reset --hard 9b4a8b4
tinyusb
git clone --recursive https://github.com/hathach/tinyusb.git ./components/arduino_tinyusb/tinyusb
git -C ./components/arduino_tinyusb/tinyusb reset --hard a0e5626bc
Сборка
Теперь можем запустить сборку для esp32 (если у вас другая ревизия платы - указывайте её):
./build.sh -t esp32
Сборка занимает продолжительное время, если по итогу создан каталог с именем «out» - операция прошла успешно.
$ ls out
package_esp32_index.template.json platform.txt tools
Sdkconfig
Если хотите, можете посмотреть текущие настройки sdkconfig:
. ./esp-idf/export.sh
idf.py menuconfig
Можно использовать menuconfig
только для просмотра настроек сборки, редактировать здесь настройки не выйдет.
![интерфейс menuconfig](https://habrastorage.org/getpro/habr/upload_files/f12/7ed/8ab/f127ed8ab07ede4e4c95c38db901f036.png)
Нужная мне опция находится в Component config ---> FreeRTOS ---> Enable FreeRTOS to collect run time stats. Как видим, по умолчанию флаг сброшен:
![меню freertos](https://habrastorage.org/getpro/habr/upload_files/45e/4f7/fa5/45e4f7fa5d3200201a7f5cefec1c6769.png)
Нужно внести изменения относительно стандартного sdkconfig. Для esp32 нужно отредактировать configs/defconfig.esp32
. Для esp32c2 и esp32c3 результирующее имя файла — defconfig.esp32c2
и defconfig.esp32c3
соответственно (рядом можете найти и другие ревизии).
CONFIG_BTDM_CTRL_MODE_BTDM=y
CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=20
CONFIG_BT_BTC_TASK_STACK_SIZE=8192
CONFIG_BT_BTU_TASK_STACK_SIZE=8192
CONFIG_BT_CLASSIC_ENABLED=y
CONFIG_BT_A2DP_ENABLE=y
CONFIG_BT_SPP_ENABLED=y
CONFIG_BT_HFP_ENABLE=y
CONFIG_BT_STACK_NO_LOG=y
CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y
CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_OCCUPY_HSPI_HOST=y
CONFIG_ESP32_ULP_COPROC_ENABLED=y
CONFIG_ESP32_XTAL_FREQ_AUTO=y
# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
CONFIG_FREERTOS_FPU_IN_ISR=y
# CONFIG_USE_WAKENET is not set
# CONFIG_USE_MULTINET is not set
CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y
CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y
CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y
CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
Я добавил последнюю строку для включения функций сбора статистики. Все прочие уже были в файле.
Собираем все заново:
./build.sh -t esp32
После завершения сборки проверяем конфиг сборки (каждый раз нужно делать экспорт):
. ./esp-idf/export.sh
idf.py menuconfig
Если нужный флаг установлен - мы все сделали правильно.
![меню freertos с измененным флагом](https://habrastorage.org/getpro/habr/upload_files/589/d86/46c/589d8646c565bae98b9567beca1cc4a3.png)
PlatformIO
Осталось дело за малым, скопировать нашу библиотеку в PlatformIO.
Предварительно соxраняем исходную библиотеку и копируем собранную в PlatformIO:
mv -r ~/.platformio/packages/framework-arduinoespressif32/tools/sdk/ ./platformio-sdk-backup/
cp -r ./out/tools/sdk ~/.platformio/packages/framework-arduinoespressif32/tools
Можно переходить в PlatformIO и попробовать собрать прошивку, функции должны быть доступны.
Вот такой минимальный код можно использовать для проверки:
#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void TaskLog(void *pvParameters) {
static const int statsBufferSize = 1024;
static char statsBuffer[statsBufferSize];
static const int listBufferSize = 1024;
static char listBuffer[listBufferSize];
while (true) {
Serial.println("\n============ Task Stats ============");
// Get runtime stats for CPU usage
// This requires configGENERATE_RUN_TIME_STATS to be enabled
vTaskGetRunTimeStats(statsBuffer);
Serial.println("Run Time Stats:");
Serial.println(statsBuffer);
// Get task list with state, priority, stack, and task number
// Note: vTaskList output depends on configuration and may not include core affinities by default
vTaskList(listBuffer);
Serial.println("Task List:");
Serial.println(listBuffer);
Serial.println("=====================================");
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void setup() {
// Инициализация последовательного порта
Serial.begin(115200);
Serial.println("ESP32 example with stats");
// Создание задачи для вывода логов на ядре 1
xTaskCreatePinnedToCore(
TaskLog, // Функция задачи
"Log", // Имя задачи
2048, // Увеличили размер стека для доп. вычислений
NULL, // Параметры задачи
1, // Приоритет задачи
NULL, // Дескриптор задачи
1 // Ядро, на котором будет выполняться задача
);
}
void loop() {
delay(1000);
}
Каждые 5 секунд в консоль выводится статистика по загрузке CPU каждой задачей, а также список задач:
============ Task Stats ============
Run Time Stats:
Log 11614 <1%
IDLE0 20176378 97%
IDLE1 20618561 99%
loopTask 1060 <1%
esp_timer 24 <1%
Tmr Svc 22 <1%
ipc1 47571 <1%
ipc0 32460 <1%
Task List:
Log X 1 624 10
IDLE0 R 0 552 5
IDLE1 R 0 548 6
loopTask B 1 7292 8
Tmr Svc B 1 1584 7
ipc1 B 24 484 2
ipc0 B 24 508 1
esp_timer S 22 4096 3
=====================================
Вот таким замысловатым способом вы можете менять параметры библиотеки esp32-arduino для использования в PlatformIO.
Список параметров значительно шире, чем включение функций получения статистики, жаль что IDE не предоставляют более удобный способ конфигурирования основных библиотек.
UPD
Сообщество PlatformIO также предложило использовать pioarduino — форк платформы platform-espressif32, — чтобы включить поддержку последней версии Espressif32 Arduino 3.x в PlatformIO. Эта версия включает встроенную поддержку статистических функций. PlatformIO пока официально не поддерживает Arduino 3.x. Кроме того, между этими версиями есть довольно значительные различия.
UPD 2
Если вы используете Arduino IDE - можно использовать библиотеку esp32 3.*
от espressiv systems вместо ардуиновской, там эти функции включены по умолчанию. В остальном описанный алгоритм остается актуальным для изменения других параметров sdkconfig для обеих IDE. Спасибо @shadrapза помощь.
Комментарии (7)
4chemist
02.02.2025 08:43Статья сподвигла глянуть что да как с загрузкой CPU. Благо у меня чистый ESP-IDF, так что включил без приседаний. Всё казалось, что там серьезная нагрузка.
А оказалось...
Скрытый текст
twaiCtrlTask 711 <1%
IDLE1 301186298 99%
IDLE0 296722385 98%
telnet 685233 <1%
tiT 492071 <1%
ledTask 6394 <1%
fp2CheckAliveAv 2691 <1%
main 449385 <1%
relayTask 1285 <1%
twaiTxTask 12283 <1%
powerMeterTask 10 <1%
logToFileTask 294137 <1%
mdns 60982 <1%
ipc1 463250 <1%
ipc0 220077 <1%
sys_evt 15305 <1%
httpd 883169 <1%
wifi 2719499 <1%
twaiRxTask 103842 <1%
esp_timer 315391 <1%
Tmr Svc 13 <1%positroid Автор
02.02.2025 08:43Я в отсутствие этих функций пытался написать свою статистику через micros(), но потерпел фиаско на http-сервере, который с таким подходом показывал 50% загрузки в простое (очевидно задача ожидания http-запроса выполняется не последовательно и замера через micros в начале и конце задачи недостаточно).
Поэтому решил все же добить тему получения статистики и увидел те же <1% у http сервера)
Меня это все интересует прежде всего в рамках esp32-cam и потоковой передачи видео, пока кажется, что она должна неплохо нагружать контроллер, но до реализации пока не добрался.
shadrap
Наверное я вас не понял , а просто им единички вместо 0 поставить в FreeRTOSConfig.h :
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() / #endif / CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS / #ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS #define configUSE_STATS_FORMATTING_FUNCTIONS 1 / Used by vTaskList() / #endif / CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS */
не достаточно ?
positroid Автор
Увы, platformio использует уже скомпилированные библиотеки так называемого esp32 arduino core и конфигурация FreeRTOS через константы невозможна. Если я правильно понял - то с Arduino IDE ситуация та же, если вдруг ошибаюсь - напишите кто-нибудь, скорректирую статью.
Добавил упоминание Platformio / Arduino IDE в начало статьи, чтобы было понятнее, до ката это указано. Если все собирать полностью из исходников - такой проблемы быть не должно.
В UPD добавил вариант попроще с заменой платформы на кастомную, но там тоже готовая сборка библиотек
shadrap
Не буду фантазировать , давно не брал в руки platformio , как то хватает Arduino, может быть я и ошибаюсь , но раньше можно было использовать как пре-компилед библиотеки так и нет. В Arduino он лежит в инклудниках RTOS , в последних билдах отчеты включены по умолчанию.
positroid Автор
Сходу не вышло подтвердить вашу гипотезу, код из статьи не собирается в Arduino IDE по причине отсутствия указанных функций, define ситуацию не спасает, а для подмены библиотеки по описанной в статье схеме нужно пересобирать esp32-arduino уже с совсем другими версиями пакетов.
Возможно, я что-то упускаю и можно в Arduino IDE использовать другой подход, нужно изучить детальнее
positroid Автор
Разобрались в личке, добавил UPD 2 и скорректировал статью - действительно в Arduino IDE можно использовать эти функции, если подключить 3.* версию библиотеки esp32 от espressiv systems взамен ардуиновской.