Работа с группами событий FreeRTOS в ESP32 с использованием ESP-IDF


В данной статье мы рассмотрим как использовать группы событий FreeRTOS для синхронизации задач в ESP32 с использованием ESP-IDF. Часто мы сталкиваемся с ситуацией, когда выполняется несколько задач одновременно и требуется их синхронизация. Это может включать в себя совпадение или расхождение событий, а также проверку синхронизации между различными задачами. Библиотека FreeRTOS в ESP-IDF предоставляет API для создания и мониторинга групп событий. Мы покажем это на примере проекта, который мы создадим и скомпилируем в VS Code с расширением ESP-IDF, где мы будем использовать freertos/event_groups.h для синхронизации двух задач.

Работа с группами событий FreeRTOS в ESP32 с использованием ESP-IDF

Также можете посмотреть другие статьи на нашем сайте про работу с FreeRTOS в ESP32 с использованием ESP-IDF:

Группы событий FreeRTOS для ESP32 с использованием ESP-IDF

В этом разделе мы продемонстрируем работу групп событий с использованием библиотеки FreeRTOS.

Создание проекта

Откройте VS Code и перейдите в меню View > Command Palette («Вид» > «Палитра команд»). Введите в строке поиска ESP-IDF: New Project и нажмите Enter.

Укажите название проекта и каталог. Мы назвали наш проект «ESP_IDF_EVENT_GROUPS». Для платы ESP-IDF мы выбрали опцию custom board («Пользовательская плата»). В качестве целевой платформы ESP-IDF мы выбрали модуль ESP32. Нажмите кнопку ‘Choose Template’ («Выбрать шаблон»), чтобы продолжить.

Создание нового проекта для работы с группами событий FreeRTOS

В разделе «Расширение» выберите опцию ESP-IDF:

Выбор опции ESP-IDF в разделе Extension («Расширение»)

На вкладке get-started («Начало работы») мы щелкнем по пункту «sample_project». Затем нажмем ‘Create project using template sample_project’) («Создать проект, используя шаблон sample_project»).

Создание проекта с использованием шаблона sample_project

Вы получите уведомление о создании проекта. Чтобы открыть проект в новом окне, нажмите «Да».

Это открывает наш проект, который мы создали во вкладке «Проводник». Внутри папки проекта находится несколько папок. Это справедливо для каждого проекта, который вы будете создавать с помощью ESP-IDF Explorer.

Код ESP32 для работы с группами событий FreeRTOS 

В папке  main  находится исходный код, то есть файл main.c будет расположен именно здесь. Перейдите в папку main > main.c и откройте его. Скопируйте приведенный ниже код в свой файл main.c и сохраните его.

Как работает код?

Для начала мы подключим необходимые библиотеки, включая библиотеки FreeRTOS для генерации задержек, создания задач и групп событий.

Далее мы объявляем переменную 'event_group' для хранения созданной группы событий FreeRTOS. Эта группа событий FreeRTOS используется для сигнализации о возникновении события.

У нас есть две задачи, Get_Temperature и Get_Humidity, задача которых — выводить сообщение каждые несколько секунд. Задача Get_Temperature выводит сообщение “Temperature value received” («Получено значение температуры») каждую секунду, а задача Get_Humidity — сообщение “Humidity value received” («Получено значение влажности») каждые 5 секунд, когда установлены соответствующие биты события.

Для событий мы определяем два бита/флага. К ним относятся бит, указывающий на полученную температуру, и бит, указывающий на полученную влажность. Они помогут определить, произошло ли конкретное событие или нет.

Внутри функции Get_Temperature() мы вызываем xEventGroupSetBits() для установки битов в группе событий. Эта функция принимает два параметра. Первый параметр — это дескриптор группы событий, биты которой нужно установить (в нашем случае — 'event_group'). Второй параметр — это побитовое значение, которое нужно установить (в нашем случае — 'got_temp'). Мы предварительно определили его как 'BIT0'. После установки бита будет выведено сообщение, указывающее на получение значения температуры. После этого будет задержка в 1 секунду.

Аналогично, внутри функции Get_Humidity() мы вызываем xEventGroupSetBits() для установки битов в группе событий. Первый параметр — это дескриптор группы событий, биты которой необходимо установить, в нашем случае — 'event_group'. Второй параметр — это побитовое значение, которое необходимо установить, в нашем случае — 'got_hum'. Мы предварительно определили его как 'BIT1'. После установки бита будет выведено сообщение, указывающее на получение значения влажности. После этого будет задержка в 5 секунд.

Внутри функции Sender() вызывается функция xEventGroupWaitBits(). Эта функция ожидает установки одного или нескольких битов в ранее созданной группе событий. Она принимает четыре параметра.

  • Первый параметр — это идентификатор группы событий, которую необходимо проверить. В нашем случае он установлен как 'event_group'.
  • Второй параметр — это побитовое значение, указывающее, какой бит/биты следует проверить внутри группы событий. В нашем случае оно установлено как 'got_temp | got_hum'.
  • Третий параметр — 'xClearOnExit', который может принимать одно из двух значений: pdTRUE или pdFALSE. Если он установлен в pdTRUE, то все биты, установленные в группе событий, будут сброшены перед возвратом функции. Если установлен pdFALSE, то биты, установленные в группе событий, не изменяются. В нашем случае он установлен в значение 'true'.
  • Четвертый параметр — 'xWaitForAllBits', который также может принимать одно из двух значений: pdTRUE или pdFALSE. Если он установлен на pdTRUE, функция возвращает управление, когда установлены все биты или истекло максимальное время блока. Если он установлен на pdFALSE, функция возвращает управление, когда установлен хотя бы один из битов или истекло максимальное время блока. В нашем случае он установлен на 'true'.
  • Последний параметр — 'xTicksToWait', который обозначает максимальное время блокировки. В нашем случае он установлен как 'portMAX_DELAY'.

Функция Sender() ожидает наступления двух событий, а затем выводит в терминал сообщение “Sender: Received temperature and Humidity” («Отправитель: Получены температура и влажность»).

app_main()

Внутри функции app_main() мы сначала создаём группу событий с помощью функции xEventGroupCreate(). Эта функция возвращает дескриптор группы событий, который в нашем случае равен 'event_group'.

После создания группы событий мы создаём задачи для Get_Temperature, Get_Humidity и Sender. Для создания задачи мы используем функцию xTaskCreate(). Эта функция принимает несколько аргументов.

  • Первый аргумент — это имя функции.
  • Второй аргумент — это название задачи, используемое в описательных целях.
  • Третий аргумент задаёт размер стека задачи. Это указывает объём памяти, который мы хотим зарезервировать для конкретной задачи.
  • Четвертый аргумент — это параметр. Это значение, которое передается в качестве параметра создаваемой задаче. Если это свойство не используется, оно устанавливается в значение NULL.
  • Пятый аргумент — это приоритет задачи.
  • Последний аргумент — это дескриптор, используемый для изменения функции задачи, например, приостановки, удаления, возобновления, получения или установки конфигурации задачи. Он необязателен, поэтому может быть установлен как NULL.

Демонстрация работы проекта

Для прошивки микросхемы введите следующую команду в последовательном терминале. Не забудьте заменить COM-порт на тот, через который подключена ваша плата.

После успешной прошивки кода в последовательный терминал выводится следующее. Задача Get_Temperature выводит сообщение “Temperature value received” («Получено значение температуры») каждую секунду, задача Get_Humidity — “Humidity value received” («Получено значение влажности») каждые 5 секунд, а задача Sender — “Sender: Received temperature and Humidity” («Отправитель: Получены температура и влажность») после того, как произойдут оба события.

Тестирование работы проекта в окне терминала

(Проголосуй первым!)
Загрузка...
2 просмотров

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

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