Очередь сообщений - это объект RTOS, предназначенный для передачи данных между задачами и между прерываниями и задачами.
В не RTOS системе передача данных между различными подпрограммами, которые вызываются в бесконечном цикле (условно их можно назвать задачами), происходит, как правило, с помощью глобальных переменных.
Однако в многозадачной системе использование глобальных переменных крайне не рекомендуется - так как вытеснение может произойти в любой момент, необходимо реализовать для доступа к глобальной переменной критическую секцию, что может привести к значительной трате ресурсов. Поэтому передача данных в RTOS как правило реализуется с помощью специальных объектов - очередей сообщений.
Кроме защиты сообщений, объект реализует очередь, то есть возможность передать несколько сообщений, которые могут быть обработаны принимающей стороной позднее.
Очередь сообщений ассоциируется со структурой управления и буфером сообщений. Буфер является очередью типа FIFO, т.е. первым будет получено сообщение, которое отправлено раньше.
В TNKernel под сообщением (т.е. элементом, который хранится в буфере) понимается указатель на данные, а не сами данные. Другими словами - сообщение это не данные, а указатель на данные. Такой подход имеет как плюсы, так и минусы.
Плюсы:
Минусы:
Тем не менее, в качестве сообщения можно передавать не указатель, а например, код команды - для этого необходимо явно привести типы при передаче параметров в сервисы отсылки и приема сообщения.
Основными сервисами управления очередями сообщений являются отсылка сообщения и прием сообщения.
Если задача вызывает сервис приема сообщения, а в буфер очереди пуст, задача переводится в состояние ожидания, до тех пор, пока сообщение не будет отправлено другой задачей или пока не истечет таймаут.
Если задача вызывает сервис передачи сообщения, а буфер сообщения полон, то она переводится в состояние ожидания до тех пор, пока хотя бы одно сообщение не будет принято.
Каждая очередь сообщений ассоциируется со структурой управления:
typedef struct _TN_DQUE_S { CDLL_QUEUE_S wait_send_list; CDLL_QUEUE_S wait_receive_list; void ** data_fifo; TN_UWORD num_entries; TN_UWORD tail_cnt; TN_UWORD header_cnt; TN_OBJ_ID id_dque; } TN_DQUE_S;
В состав структуры очереди входят следующие элементы:
wait_send_list |
Очередь задач, посылающих сообщение |
wait_receive_list |
Очередь задач, принимающих сообщение |
data_fifo |
Указатель на буфер сообщений. Буфер сообщений это массив указателей на void |
num_entries |
Объем буфера (максимальное количество сообщений в очереди) |
tail_cnt |
Индекс принимаемого сообщения |
header_cnt |
Индекс отсылаемого сообщения |
id_dque |
Поле идентификации объекта как очереди сообщений |
TN_DEBUG
. Тем не менее, прямой доступ к элементам структуры крайне не рекомендуется, так как это является вмешательством в работу планировщика и других сервисов RTOS.
TNKernel имеет следующий набор функций (сервисов) для управления очередями сообщений:
Сервис | Описание | Свойства |
---|---|---|
Создание и удаление очереди сообщений | ||
tn_queue_create() | Создание очереди | |
tn_queue_delete() | Удаление очереди | |
Отсылка сообшения | ||
tn_queue_send() | Отсылка сообшения | |
tn_queue_send_polling() | Отсылка сообщения без блокировки задачи | |
tn_queue_isend_polling() | Отсылка сообщения из прерывания | |
Прием сообщения | ||
tn_queue_receive() | Прием сообщения | |
tn_queue_receive_polling() | Прием сообщения без блокировки задачи | |
tn_queue_ireceive() | Прием сообщения в прерывании |