воскресенье, 4 октября 2026 г.

STM32 FreeRTOS уведомления задач

 Операционная система FreeRTOS содержит некоторое количество инструментов для коммуникации задачи и обработчиков прерываний между собой. Для этого можно использовать бинарные семафоры и даже, рассмотренные ранее, очереди но если нужно организовать максимально быстрое и не затратное по памяти решение то лучше всего подойдут "уведомления задач" (Task Notifications). Уведомления задач имеются в новых версиях FreeRTOS и могут передавать не только уведомления но и некоторое небольшое количество данных, 32 бита. Уведомления задач на 40% работают быстрее бинарных семафоров и в 90% случаев могут их заменить. Попробуем изучить уведомления задач на простом примере. Допустим у нас есть прерывание по приему на UART1 после получения данных в UART1, в обработчике прерывания, упакуем принятый байт данных и отправим как уведомление в задачу.Задача примет байт и отправит его в UART1. Таким образом мы получим простой эхо режим, работающий через задачу и использующий уведомление задачи. Чтобы использовать уведомление задачи нужно сначала инициализировать её хэндл.

В функции main когда мы создаем задачу то в функцию xTaskCreate, последним параметром, передаем этот хэндл.
Он, в последствии, будет использоваться для передачи уведомлений. Периферию настраиваем как обычно, включаем UART1, 
не будем на этом останавливаться см. предыдущие уроки.

Сейчас нас интересуют две функции. Это сама задача и обработчик прерывания по приему UART1.
В обработчике прерывания принимаем байт.
Далее используя специальную функцию для отправки уведомлений задачам из прерывания.
Отправляем уведомление задаче. Важно в прерывании использовать именно такую функцию. Если нужно отправить уведомление от задачи к задаче то есть другая похожая.
В этой функции хэндл задачи указываем первым параметром. Вторым параметром передаем принятый байт, предварительно приведя его к нужному типу.
Третьим параметром передаем константу означающую перезапись значения если задача не успела его вовремя принять и обработать. 
Ну и остальное просто оставим пока как есть. В самой задаче, объявляем переменную в которую будем принимать байт от UART1.
В бесконечном цикле задачи проверяем когда в задачу придет уведомление. Когда оно приходит, извлекаем принятый байт.
После отправляем его обратно в UART1.
Полный код файла main.c проекта, можно скопировать от сюда:

Его можно вставить в свой проект и откомпилировать запустив скрипт. О том как скачать и настроить проект а также откомпилировать см. первый урок по FreeRTOS. Если откомпилировать проект получилось то можно его загрузить в микроконтроллер. Подключить его через usb-uart переходник к компьютеру и в каком либо терминале последовательного порта наблюдать работу.


Адрес биткоин кошелька для поддержки канала - bc1qlhrmmkh77x2lzhqe4lt9qwkglswj64tsqt2l5g

суббота, 3 октября 2026 г.

Визуализация работы кольцевого буфера

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

Кольцевой буфер с перезаписью (Overwrite)

➔
➔
Буфер пуст

Адрес биткоин кошелька для поддержки канала - bc1qlhrmmkh77x2lzhqe4lt9qwkglswj64tsqt2l5g