Программирование ARM Очереди FreeRTOS Mon, July 13 2020  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Очереди FreeRTOS Печать
Добавил(а) microsin   

Очереди FreeRTOS предоставляют собой основную форму обмена данными между процессами приложения. Очереди могут использоваться для отправки сообщений между задачами, и между прерываниями и задачами. В большинстве случаев они используются как безопасный для использования в потоках стек буферов (thread safe FIFO, First In First Out, работающий по принципу первым вошел первым вышел), когда новые данные помещаются в конец очереди (xQueueSendToBack), хотя данные также могут отправляться в начало очереди (xQueueSendToFront).

На рисунке ниже показан пример записи в очередь и чтения из неё. В этом примере очередь была создана на 5 ячеек, и при использовании она никогда не переполняется.

FreeRTOS queue animation

[Пользовательская модель очередей FreeRTOS]

Модель использования очередей FreeRTOS комбинирует в себе простоту и гибкость – атрибуты, которые обычно являются взаимоисключающими. Сообщения пересылаются через очередь как копия, т. е. данные (которые могут быть указателем или буфером большего размера) сами копируются в очередь вместо того, чтобы сохранять в очереди только указатели на данные. Это самый лучший подход по следующим причинам:

• Маленькие сообщения, которые уже содержатся в переменных языка C (целые числа типа uint8_t, int, маленькие структуры и т. п.) можно посылать в очередь непосредственно. Нет необходимости выделять в памяти буфер для сообщения и копировать туда переменную. Подобным образом сообщения могут непосредственно считываться из очередей в переменные языка C.

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

• Использование очередей, которые передают через себя данные как копию не запрещает использовать эти очереди для передачи сообщений по ссылке. Когда размер сообщения достигает значения, когда становится непрактичным копирование всего сообщения в очередь байт за байтом, можно определить очередь для хранения указателей, и копировать в сообщение только указатель на данные. Именно так реализация FreeRTOS+UDP [4] передает большие сетевые буферы по стеку FreeRTOS IP.

• Ядро берет на себя полную ответственность за выделение памяти, используемой в качестве области хранения очереди.

• Сообщения переменного размера могут быть переданы путем определения очереди для хранения структур, в которых содержится 2 поля - одно поле указывает на помещаемое в очередь сообщение, другое поле хранит размер этого сообщения.

• Одну очередь можно использовать для приема сообщений различных типов, и сообщений из различных отправителей, путем определения очереди для хранения структуры, в которой одно поле содержит тип сообщения, а другое поле данные сообщения (или указатель на данные сообщения). Как интерпретируются данные - зависит от типа сообщения. Именно так задача, управляющая IP-стеком FreeRTOS+UDP, может использовать одну и ту же очередь для нескольких целей - приема уведомлений о событиях таймера ARP, пакетов от оборудования Ethernet, пакетов от приложения, событий отключения сети и т. д.

• Реализация очереди FreeRTOS по своей сути подходит для использования в системе с защитой областей памяти (memory protected environment). Задача, работа которой ограничена для своей выделенной, защищенной области памяти, может передать данные другой задаче, которая в свою очередь ограничена использованием своей отдельной защищенной области памяти. Так происходит потому что вызов функции FreeRTOS для обращения к очереди повышает уровень привилегий микроконтроллера. К области хранения очереди имеет полный доступ только код FreeRTOS (работающий с полными привилегиями).

• Предоставляются отдельные API-функции для использования очереди в обработчике прерывания (ISR). Использования отдельных API-функций (одна для использования в задаче FreeRTOS, другая для использования в ISR) избавляет код FreeRTOS от лишних накладных расходов на проверку контекста вызова функции (прерывание это или нет) всякий раз при её вызове. Использование отдельного API для прерываний также означает, в большинстве случаев, более простое для пользователя создание обработчиков прерывания - в сравнении с другими альтернативными RTOS.

Так или иначе, FreeRTOS API и его использование становится проще.

Существуют обучающие материалы ([3] и перевод документации на русский язык [5]), где предоставляется дополнительная информация по очередям, двоичным семафорам, мьютексам, семафорам со счетчикам и рекурсивным семафорам, вместе с простыми рабочими примерами, поставляемыми в распространяемом пакете FreeRTOS.

[Блокировка на очереди]

API-функции очереди позволяют задавать время блокировки на очереди.

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

Когда задача пытается записать заполненную очередь, она помещается в состояние Blocked (в этом состоянии она не использует процессор, предоставляя его для других задач) до тех пор, пока в очереди не появится место для записи сообщения, или когда истечет указанное время блокировки на очереди.

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

Секцию документации Queue Management (или русский перевод [5]) для получения списка связанных с очередями API-функций. Поиск файлов в директории FreeRTOS/Demo/Common/Minimal предоставит множество примеров использования очередей.

Обратите внимание на то, что прерывания (ISR) НЕ ДОЛЖНЫ использовать API-функции, которые не заканчиваются на "FromISR".

[Подключение заголовка queue.h]

Использование очередей, тип QueueHandle_t, подразумевает определение этого типа с помощью подключения заголовочного файла queue.h директивой #inclide "queue.h". Однако при попытке прямого подключения заголовочного файла queue.h компилятор выдаст ошибку, которая запрограммирована в коде FreeRTOS:

Fatal Error[Pe035]: #error directive: "include FreeRTOS.h" must appear in source files before "include queue.h"

Очевидно, что разработчики FreeRTOS требуют вместо подключения queue.h подключать файл FreeRTOS.h. Но не все так просто: если подключить файл FreeRTOS.h (директивой #include "FreeRTOS.h"), тип QueueHandle_t не определяется:

Error[Pe020]: identifier "QueueHandle_t" is undefined M:\asm\radiopager\Inc\vars.h 11

Решить проблему можно, если подключить вместо FreeRTOS.h заголовочный файл cmsis_os.h:

#include "cmsis_os.h"

[Ссылки]

1. FreeRTOS Queues site:freertos.org.
2. Блокировка на нескольких объектах FreeRTOS.
3. FreeRTOS Documentation PDF files site:freertos.org.
4. FreeRTOS+UDP site:freertos.org.
5. FreeRTOS: практическое применение, часть 2 (управление очередями).

 

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


Защитный код
Обновить

Top of Page