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



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

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

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

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

 

 

 

где

 

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

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

 

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

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

 

 

Проект был сделан из проекта урока 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 и создадим наши задачи

 

 

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

 

 

 

 

 

 

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

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

 

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

 

Данная статья в Дзен.

 

 

Предыдущий урок Программирование МК ESP32 Следующий урок

 

Исходный код

 

 

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

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

Дисплей LCD 20×4 можно приобрести здесь Дисплей LCD 20×4

Дисплей LCD 16×2

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

 

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

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

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

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

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

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

*