Перейти к содержимому

Добрый день, уважаемый читатель!

В прошлых статьях мы обсуждали, как настроить проект PlatformIO и ESP-IDF (если вы не знакомы с этими разделами, но статьи почему-либо пропустили, рекомендую ознакомиться). Но в реальном проекте нам дополнительно может понадобиться довольно большое количество “прикладных” параметров, которые не входят в “стандартные” файлы конфигурации ESP-IDF. Например:

  • номера выводов GPIO, задействованные в проекте
  • имя WiFi сети и пароль доступа
  • адрес MQTT сервера, логин и пароль доступа
  • токен доступа к Telegram-боту
  • размеры стеков прикладных задач

и многое-многое другое…

 


Для чего нужен “свой” файл конфигурации проекта?

Как я уже писал в статье, посвященной конфигурированию ESP-IDF, в принципе, всё это и многое другое можно запихнуть в тот же sdkconfig.h. В этом случаем мы получим универсальный инструмент конфигурации, в котором будут собраны и “стандартные” и “прикладные” параметры, и который к тому же будет автоматически доступен из всех ваших файлов прикладных задач и библиотек (через include "sdkconfig.h"). В принципе, этот вариант вполне имеет право на существование, и как бы автоматически предполагается разработчиками из Espressif. Если бы не одно “но”….

Время! Войти в меню SDK Config занимает определенное время (обычно 20…60 секунд), затем после каждого изменения конфигурации PlatformIO начнет заново компилировать все ESP-IDF библиотеки, что занимает дополнительное время. А иногда требуется подобрать тот или иной параметр (например размер стека) и это превращается в муку.

В итоге я не придумал ничего лучше, чем создать для “прикладных” задач обычный текстовый файл, который я назвал project_config.h (вы можете назвать его по другому – не суть), и в котором собраны все мои (ну почти все, на самом деле сейчас у меня их несколько) параметры проекта, не включенные в sdkconfig.h. Выглядит это просто как набор макросов препроцессора (ну в принципе как и sdkconfig.h) с комментариями:

Поменять строчку в текстовом файле прямо из редактора кода – дело пары секунд, поэтому на практике этот способ конфигурации гораздо быстрее. Но и ошибку сделать гораздо легче.

Содержимое файла конфигурации для программ на базе “моей” прошивки частью зависит от конкретной задачи, а частью это “стандартные” макросы, использующиеся во многих проектах одновременно. С примером такого файла вы можете ознакомиться по ссылке, а описание его можно найти здесь.

 


Почему именно #define (а не static const int к примеру)?

Почему я использую макросы препроцессора для объявления констант вместо явного объявления глобальных статических констант (надеюсь вы в курсе, что это такое)? Например в примере выше я использовал конструкцию:

#define CONFIG_SENSORS_TASK_CYCLE 15000

Эта строчка управляет временным циклом чтения данных с сенсоров в миллисекундах. Но можно так же это же самое записать и так:

static const uint32_t CONFIG_SENSORS_TASK_CYCLE = 15000;

Примечание: я специально не стал менять написание константы для наглядности, хотя это и не принято

На сайтах для начинающих программистов Arduino, вы наверняка видели настоятельные рекомендации использовать именно второй вариант. И они правы в данном случае! Препроцессор “ничего не знает” о типах переменных и констант, поэтому в случае использования # define легко сделать ошибку, которую будет потом нелегко найти, например так:

#define CONFIG_SENSORS_TASK_CYCLE "15000"

 

Так зачем же я всё-таки применяю исключительно #define?

Давайте взглянем на следующую строчку:

#define CONFIG_SENSORS_STATIC_ALLOCATION 1

Этот параметр определяет, как будет создана прикладная задача – в статической области памяти BSS или в куче (подробнее об этом читайте в другой статье). Так вот, здесь записать эту строку как константу уже не выйдет!

static const uint8_t CONFIG_SENSORS_STATIC_ALLOCATION = 1;

Дело в том, что это объявление далее используется в конструкции вида:

#if (CONFIG_SENSORS_STATIC_ALLOCATION == 1)
  .. статическое создание задачи
#else
  .. динамическое создание задачи
#endif // CONFIG_SENSORS_STATIC_ALLOCATION

и здесь static const чего-то там уже не может быть использована.

Вот и приходится использовать макросы препроцессора. Но не мешать же в одном и том же файле “классические” константы с макросами… 

По этой же самой причине, я полагаю, в sdkconfig.h используются только макросы препроцессора.

 


Проблема номер раз

Хорошо, зачем нужен файл – разобрались. Но при попытке применить свой файл project_config.h в общих библиотеках “вне” каталога проекта, мы очень быстро наткнемся на проблему – внешние подключенные библиотеки (то есть библиотеки, находящиеся вне поля зрения проекта и использующиеся в нескольких проектах сразу) “ничего не знают” об этом файле и мы не сможем правильно скомпилировать проект.

Решение мне подсказали на форуме PlatformIO, когда я ещё только-только начинал создавать свои библиотеки для ESP-IDF. Справедливости ради нужно сказать, что это не решение, а костыльНужно указать компилятору, где искать этот самый файл при компиляции любых файлов проекта, в том числе любых сторонних библиотек и даже ESP-IDF. Делается это с помощью директивы -i (include) компилятора. Добавить эту директиву можно в файл platformio.ini проекта:

Добавляем указание компилятору, где искать project_config.h

В моем случае я помещаю этот файл в подкаталог ./include проекта, поэтому и указываю на него в этом параметре. Вуаля – всё работает как часы. Только не забываем в нужным местах  #include ”project_config.h” добавлять, разумеется.

 


Проблема номер два

Когда проектов станет больше двух-трех, вы наверняка столкнетесь с необходимостью как-то “синхронизировать” некоторые из настроек между проектами. То есть, некоторые параметры желательно оставить только для текущего проекта, а некоторые – сделать так, чтобы изменение в одном месте привело к изменениям сразу во всех проектах, иначе дублирование “общих” настроек может занимать значительное время и сильно утомительно.

Выход из этой ситуации напрашивается сам собой. В общих библиотеках создаем один или несколько файлов, в которых размещаем необходимые настройки, по аналогии с project_config.h выше. Например у меня это выглядит так:

Общие настройки для всех проектов

В этом случае дополнительно подключать эти файлы к проекту в platformio.ini не требуется (кроме, собственно, подключения общих библиотек).

Подключение общих библиотек к проекту

Как видите, решить этот вопрос ещё проще.

 


На этом пока всё, до встречи на сайте и на dzen-канале!

💠 Полный архив статей вы найдете здесь


Пожалуйста, оцените статью:
[ 0 из 5, всего 0 оценок ]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *