====== OSA : Очереди сообщений ======
===== Введение =====
Очереди сообщений являются самым универсальным и очень полезным инструментом ОС для обмена информацией между задачами. Очереди позволяют передавать следующее сообщение, не дожидаясь освобождения предыдущего. Очереди сообщений поддерживаются и для **указателей на сообщения** и для **коротких сообщений**. Для использования очередей сообщений в программе нужно в файл ##[[osa:ref:appendix:configuration|OSAcfg.h]]## вставить определение констант:
#define OS_ENABLE_QUEUE
// Если собираемся использовать очереди
// указателей на сообщения
#define OS_ENABLE_SQUEUE
// Если собираемся использовать очереди
// коротких сообщений
Определение этих констант скажет компилятору, что в генерируемый код нужно добавить функции для работы с очередями.
В программе очереди объявляются через типы ##[[osa:ref:description:data_types#OST_QUEUE|OST_QUEUE]]## и ##[[osa:ref:description:data_types#OST_SQUEUE|OST_SQUEUE]]##:
OST_QUEUE queue; // Очередь указателей на сообщения
OST_SQUEUE squeue; // Очередь коротких сообщений
Эти определения создают в памяти дескрипторы для работы с очередями, которые содержат информацию о размере очереди, ее заполненности, а также сам указатель на очередь. Для работы с очередями нужно также выделять RAM-память для самой очереди (буфер, куда будут помещаться сообщения).
OST_MSG msg_queue[10]; // Буфер для очереди из 10 сообщений
OST_SMSG smsg_queue[15]; // Буфер для очереди из 15 коротких сообщений
Перед работой с очередью, она должна быть создана, т.е. должен быть инициализирован дескриптор очереди:
OS_Queue_Create(queue, msg_queue, 10); // Создаем очередь queue на 10 сообщений.
// Сообщения, отправляемые в очередь, будут
// храниться в массиве msg_queue.
Только после вызова этого сервиса можно отправлять сообщения в очередь и принимать их.
Для **PIC16** дескриптор очереди и буфер очереди могут находиться только в банках bank0 и bank1.
==== Объединение ====
Если в программе предполагается использование очередей обоих типов и есть уверенность в том, что **размерности** ##[[osa:ref:description:data_types#OST_MSG|OST_MSG]]## и ##[[osa:ref:description:data_types#OST_SMSG|OST_SMSG]]## одинаковы, то можно в ##[[osa:ref:appendix:configuration|OSAcfg.h]]## определить константу:
#define OS_QUEUE_SQUEUE_IDENTICAL
Это объединит функции обработки очередей разных типов, тем самым сэкономится ROM-память.
~~UP~~
===== Сервисы для работы с очередями сообщений =====
==== Очередь сообщений ====
^ Сервис ^ Аргументы ^ Описание ^ Свойства ^
| **Создание** ||||
| ##[[osa:ref:allservices:OS_Queue_Create|OS_Queue_Create]]## | ''(queue, buffer, size)'' | Создаем очередь сообщений queue, указывая буфер и его размер | {{osa:ref:attr_call_not_int.png|Нельзя вызывать из прерывания}} |
| **Отправка** ||||
| ##[[osa:ref:allservices:OS_Queue_Send|OS_Queue_Send]]## | ''(queue, message)'' | Отправляем сообщение с содержимым message в очередь queue с ожиданием свободной ячейки | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} |
| ##[[osa:ref:allservices:OS_Queue_Send_TO|OS_Queue_Send_TO]]## | ''(queue, message, timeout)'' | То же, что и ##[[osa:ref:allservices:OS_Queue_Send|OS_Queue_Send]]##, но с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} |
| ##[[osa:ref:allservices:OS_Queue_Send_Now|OS_Queue_Send_Now]]## | ''(queue, message)'' | Отправляем сообщение с содержимым message в очередь queue без ожидания свободной ячейки | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} |
| **Проверка** ||||
| ''bool ''\\ ##[[osa:ref:allservices:OS_Queue_Check|OS_Queue_Check]]## | ''(queue)'' | Проверить, есть ли сообщение в очереди. | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} |
| ''bool ''\\ ##[[osa:ref:allservices:OS_Queue_IsFull|OS_Queue_IsFull]]## | ''(queue)'' | Проверка переполненности буфера | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} |
| **Ожидание** ||||
| ##[[osa:ref:allservices:OS_Queue_Wait|OS_Queue_Wait]]## | ''(queue, os_msg_type_var)'' | Ожидаем сообщение из очереди queue | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} |
| ##[[osa:ref:allservices:OS_Queue_Wait_TO|OS_Queue_Wait_TO]]## | ''(queue, os_msg_type_var, timeout)'' | То же, что и ##[[osa:ref:allservices:OS_Queue_Wait|OS_Queue_Wait]]##, но с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} |
~~UP~~
==== Очередь коротких сообщений ====
^ Сервис ^ Аргументы ^ Описание ^ Свойства ^
| **Создание** ||||
| ##[[osa:ref:allservices:OS_Squeue_Create|OS_Squeue_Create]]## | ''(squeue, buffer, size)'' | Создаем очередь коротких сообщений squeue, указывая буфер и его размер | {{osa:ref:attr_call_not_int.png|Нельзя вызывать из прерывания}} |
| **Отправка** ||||
| ##[[osa:ref:allservices:OS_Squeue_Send|OS_Squeue_Send]]## | ''(squeue, smessage)'' | Отправляем сообщение с содержимым smessage в очередь squeue с ожиданием свободной ячейки | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} |
| ##[[osa:ref:allservices:OS_Squeue_Send_TO|OS_Squeue_Send_TO]]## | ''(squeue, smessage, timeout)'' | То же, что и ##[[osa:ref:allservices:OS_Squeue_Send|OS_Squeue_Send]]##, но с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} |
| ##[[osa:ref:allservices:OS_Squeue_Send_Now|OS_Squeue_Send_Now]]## | ''(squeue, smessage)'' | Отправляем сообщение с содержимым smessage в очередь squeue без ожидания свободной ячейки | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} |
| **Проверка** ||||
| ''bool ''\\ ##[[osa:ref:allservices:OS_Squeue_Check|OS_Squeue_Check]]## | ''(squeue)'' | Проверить, есть ли сообщение в очереди. | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} |
| ''bool ''\\ ##[[osa:ref:allservices:OS_Squeue_IsFull|OS_Squeue_IsFull]]## | ''(squeue)'' | Проверка переполненности буфера. Возвращает true, если в очереди нет места. | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} |
| **Ожидание** ||||
| ##[[osa:ref:allservices:OS_Squeue_Wait|OS_Squeue_Wait]]## | ''(squeue, os_smsg_type_var)'' | Ожидаем сообщение из очереди squeue | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} |
| ##[[osa:ref:allservices:OS_Squeue_Wait_TO|OS_Squeue_Wait_TO]]## | ''(squeue, os_smsg_type_var, timeout)'' | То же, что и ##[[osa:ref:allservices:OS_Squeue_Wait|OS_Squeue_Wait]]##, но с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} |
~~UP~~