|
В ESP-IDF есть два основных способа узнать дату и время компиляции приложения: из логов запуска и непосредственно в коде программы.
Способ 1: посмотреть в логах запуска (самый простой)
При запуске ESP-IDF приложение автоматически выводит в лог (в монитор порта) информацию о времени компиляции. Обратите внимание на строки, начинающиеся с `cpu_start`:
I (304) cpu_start: Compile time: Мар 14 2022 18:44:58 I (316) cpu_start: ESP-IDF: v4.3.2
Если вы используете монитор порта (например, командой `idf.py monitor`), то эта информация отображается сразу после перезагрузки чипа.
Способ 2: получить дату компиляции в коде
Для этого вы можете использовать стандартные макросы __DATE__ и __TIME__, как извлечь из них полезную информацию показано далее.
Важное примечание: режим воспроизводимой сборки (Reproducible Builds). Начиная с версии ESP-IDF v5.0, в проектах появилась опция CONFIG_APP_REPRODUCIBLE_BUILD (настраивается через `idf.py menuconfig` в разделе `Application manager`). Подробнее про Reproducible Builds см. [1].
● Если опция отключена (по умолчанию): дата и время компиляции записываются в прошивку корректно. Вы увидите их и в логах, и в коде.
● Если опция включена: система не записывает реальное время сборки в бинарный файл. Это делается для того, чтобы при каждой компиляции получался строго одинаковый бинарник (удобно для версионного контроля). При этом в логах запуска строка `Compile time:` отсутствует, и при вызове esp_app_get_description() поля date и time будут пустыми или содержать значения по умолчанию.
Если вы не видите время компиляции в логах, проверьте, не включена ли эта опция в конфигурации вашего проекта.
[Как преобразовать дату и время компиляции в текстовый формат "YYMMDD hh:mm:ss"]
#include "esp_log.h" #include < stdio.h>
static void show_compile_time(void) { // Используем стандартные макросы препроцессора // __DATE__: "MMM DD YYYY" (например "Mar 30 2026") // __TIME__: "hh:mm:ss" (например "14:25:33")
int day, year; char month_str[4]; int hour, minute, second;
// Парсим дату и время из макросов sscanf(__DATE__, "%s %d %d", month_str, &day, &year); sscanf(__TIME__, "%d:%d:%d", &hour, &minute, &second);
// Преобразуем название месяца в номер int month = 0; const char *months[] = {"Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; for (int i = 0; i < 12; i++) { if (strcmp(month_str, months[i]) == 0) { month = i + 1; break; } }
// Форматируем в "YYMMDD hh:mm:ss" char formatted_time[20]; sprintf(formatted_time, "%02d%02d%02d %02d:%02d:%02d", year % 100, month, day, hour, minute, second);
printf("Версия программы: %s\n", formatted_time);
}
Важные замечания
1. Пробелы в __DATE__: если день месяца меньше 10, в строке будет лишний пробел. Например: `"Mar 9 2025"`. Приведенный выше код с функцией sscanf корректно обрабатывает это, так как `%s` и `%d` игнорируют пробелы.
2. Reproducible Builds: если включена опция CONFIG_APP_REPRODUCIBLE_BUILD, то поля `date` и `time` будут пустыми. В этом случае ни один из способов не сработает, и нужно либо отключить эту опцию, либо использовать макросы __DATE__ и __TIME__ (которые тоже могут быть зафиксированы в зависимости от настроек компилятора).
[Ссылки]
1. ESP-IDF: воспроизводимые сборки. |