Найти тему
narod stream

ESP32 Урок 17. FreeRTOS. Счётные семафоры

На прошлом уроке мы уже работали с семафорами, но это были двоичные семафоры. Теперь на повестке дня семафоры счётные. Двоичные семафоры от счётных практически не отличаются ничем, только количество элементов в них всегда равно одному, а в счётных — более одного.

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

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

Для создания счётного семафора применяется вот такая функция

где

uxMaxCount – Максимальное значение счётчика, которое может быть достигнуто. Когда семафор достигает этого значения, его больше нельзя отдать.

uxInitialCount – Значение счётчика, присвоенное семафору при его создании.

С остальными функциями мы познакомимся при написании нашего проекта.

Схема наша со времён предыдущего урока не изменилась

-2

Проект был сделан из проекта урока 7 с именем I2C_LCD2004 и получил имя CNT_SEM_LCD.

Откроем наш проект в Espressif IDE и в функции app_main файла main.c удалим объявление переменной и массива

uint16_t i=0;
char str01[10];

Вот это объявление также удалим

qLCDData xLCDData;

Удалим также и весь код после строки

LCD_ini();

до бесконечного цикла.

В бесконечном цикле оставим только задержку

while (1) {
vTaskDelay(100 / portTICK_PERIOD_MS);
}

Сегодня давайте объявим и создадим семафор сразу в функции, не будем использовать глобальный указатель

Логика проекта будет следующая. Мы создали семафор с максимальным значением счёта 3, проинициализировали его нулём, то есть забирать нам оттуда пока нечего. Далее мы создадим 4 задачи, 3 из которых будут семафор отдавать, а одна — забирать.

Выше функции app_main добавим функции для наших задач — пока для трёх

Код во всех задачах аналогичный. Мы забираем указатель на семафор из параметров, считаем с задержкой в полсекунды в первой задаче до 10, во второй — до 20, в третьей — до 30, отображая процесс счёта на дисплее в каждой задаче на определённой строке дисплея и по окончанию счёта отдаём семафор, в результате чего у нас как раз наш семафор и достигнет максимального значения. Функция xSemaphoreGive возвращает значение pdTRUE или pdFALSE, по которому можем узнать, смогли ли мы отдать семафор, но мы этого делать не будем, чтобы не усложнять наш код. У нас три задачи и максимальное значение счёта также три, поэтому ошибок у нас не будет.

Ниже добавим функцию для четвёртой задачи

Здесь мы также получаем указатель на семафор из параметров и в цикле пытаемся его забрать, так как цикл у нас имеет три итерации, то значит, что пока мы не заберём все три элемента семафора, то мы ниже цикла не провалимся и код наш не выполнится, то есть счётчик нашей задачи не начнёт считать. Таким образом, чтобы счётчик в четвёртой задаче запустился, все три остальные задачи должны отработать, то есть отдать нам семафор. Вот в этом и суть счётного семафора в проектах подобных нашему. Мы получим сигнал тогда, когда произойдут все три события.

Вернёмся в функцию app_main и создадим наши задачи

Соберём код, прошьём контроллер и посмотрим результат

-3
-4
-5
-6
-7

Всё работает так, как и было задумано. Как только три задачи отработали (все три события произошли), код в четвёртой задаче продолжил выполняться.

Итак, на данном уроке мы познакомились со счётными семафорами, как ещё с одним видом инструмента для синхронизации задач и межпроцессным взаимодействием в операционных системах реального времени, со смыслом их использования, а также продолжили знакомство на практике. Возможно, мы продолжим в будущем знакомство с данными видом семафоров в плане их использования в прерываниях, хотя большой разницы в коде там не будет.

Всем спасибо за внимание!

Оригинал статьи находится здесь.

<<Предыдущий урок | Следующий урок>>

Исходный код

Недорогие отладочные платы ESP32 можно купить здесь

Логический анализатор 16 каналов можно приобрести здесь

Дисплей LCD 20x4 можно приобрести тут

Дисплей LCD 16x2 можно приобрести тут

Переходник I2C to LCD1602 2004 можно приобрести здесь

Видео в RuTube

Программирование МК ESP32. Урок 17. FreeRTOS. Счётные семафоры

Видео в Дзен

Видео в Youtube