Available Languages?:

TNKernel : Очереди сообщений

Введение

Очередь сообщений - это объект RTOS, предназначенный для передачи данных между задачами и между прерываниями и задачами.

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

Однако в многозадачной системе использование глобальных переменных крайне не рекомендуется - так как вытеснение может произойти в любой момент, необходимо реализовать для доступа к глобальной переменной критическую секцию, что может привести к значительной трате ресурсов. Поэтому передача данных в RTOS как правило реализуется с помощью специальных объектов - очередей сообщений.

Кроме защиты сообщений, объект реализует очередь, то есть возможность передать несколько сообщений, которые могут быть обработаны принимающей стороной позднее.

Очередь сообщений ассоциируется со структурой управления и буфером сообщений. Буфер является очередью типа FIFO, т.е. первым будет получено сообщение, которое отправлено раньше.

В TNKernel под сообщением (т.е. элементом, который хранится в буфере) понимается указатель на данные, а не сами данные. Другими словами - сообщение это не данные, а указатель на данные. Такой подход имеет как плюсы, так и минусы.

Плюсы:

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

Минусы:

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

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

Основными сервисами управления очередями сообщений являются отсылка сообщения и прием сообщения.

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

В 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() Прием сообщения в прерывании Разрешен вызов только в прерывании Может привести к переключению контекста
 
tnkernel/ref/dqueue/intro.txt · Последние изменения: 21.07.2008 01:38 От admin
 
Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki