Почтовые ящики:введение и основные услуги
Посмотреть серию раскрытых ОСРВ
Почтовые ящики были описаны в предыдущей статье. Это, пожалуй, второй после сигналов простой способ межзадачного взаимодействия, поддерживаемый Nucleus SE. Они предоставляют недорогие, но гибкие средства передачи простых сообщений между задачами.
Использование почтовых ящиков
В Nucleus SE почтовые ящики настраиваются во время сборки. Для приложения может быть настроено не более 16 почтовых ящиков. Если почтовые ящики не настроены, в приложение не включаются никакие структуры данных или код вызова службы, относящиеся к почтовым ящикам.
Почтовый ящик - это просто место для хранения, достаточно большое, чтобы вместить одну переменную типа ADDR . , доступ к которому контролируется, чтобы его можно было безопасно использовать в нескольких задачах. Одна задача может писать в почтовый ящик. Затем он заполняется, и никакая задача не может быть отправлена на него, пока задача не прочитает почтовый ящик или почтовый ящик не будет сброшен. Попытка отправить в полный почтовый ящик или прочитать из пустого может привести к ошибке или приостановке задачи, в зависимости от параметров, выбранных в вызове API, и конфигурации Nucleus SE.
Почтовые ящики и очереди
В некоторых реализациях ОС почтовые ящики не реализованы, и в качестве альтернативы рекомендуется использование очереди с одной записью. Это звучит разумно, поскольку такая очередь будет обеспечивать те же функции, что и почтовый ящик. Однако очередь представляет собой более сложную структуру данных, чем почтовый ящик, и несет в себе значительно больше накладных расходов по данным (указатели на начало и конец и т. Д.), Коду и времени выполнения.
В Nucleus SE, как и в Nucleus RTOS, у вас есть выбор обоих типов объектов и вы можете принять решение самостоятельно.
Стоит рассмотреть альтернативный подход, если ваше приложение включает несколько очередей, но, возможно, один почтовый ящик. Замена этого почтового ящика очередью повлечет за собой небольшие накладные расходы на данные, но устранит весь API-код, связанный с почтовым ящиком. Было бы очень легко настроить приложение в обоих направлениях и сравнить объем памяти и производительность.
Очереди будут обсуждаться в следующих статьях.
Настройка почтовых ящиков
Количество почтовых ящиков
Как и в большинстве аспектов Nucleus SE, конфигурация почтовых ящиков в первую очередь контролируется #define . операторы в nuse_config.h . Ключевой параметр: NUSE_MAILBOX_NUMBER . , который определяет, сколько почтовых ящиков настроено для приложения. По умолчанию установлено значение 0 (т.е. почтовые ящики не используются), и вы можете установить любое значение до 16. Ошибочное значение приведет к ошибке времени компиляции, которая генерируется тестом в nuse_config_check.h сильный> (он включен в nuse_config.c и, следовательно, скомпилирован с этим модулем), что приводит к ошибке #error выписка составляется.
Выбор ненулевого значения является «основным включением» для почтовых ящиков. Это приводит к тому, что некоторые структуры данных определяются и имеют соответствующий размер, о чем подробнее в следующей статье. Он также активирует настройки включения API.
Включает API
Каждая функция API (вызов службы) в Nucleus SE имеет разрешающий #define символ в nuse_config.h . Для почтовых ящиков это:
NUSE_MAILBOX_SEND
NUSE_MAILBOX_RECEIVE
NUSE_MAILBOX_RESET
NUSE_MAILBOX_INFORMATION
NUSE_MAILBOX_COUNT
По умолчанию все они имеют значение FALSE . , таким образом отключая каждый вызов службы и запрещая включение любого кода реализации. Чтобы настроить почтовые ящики для приложения, вам необходимо выбрать вызовы API, которые вы хотите использовать, и установить для их символов включения значение ИСТИНА . .
Вот выдержка из файла nuse_config.h по умолчанию файл.
/ * Количество почтовых ящиков в система - 0–16 * / #define NUSE_MAILBOX_NUMBER 0 / * Активаторы сервисного вызова:* / #define NUSE_MAILBOX_SEND FALSE #define NUSE_MAILBOX_RECEIVE FALSE #define NUSE_MAILBOX_RESET FALSE #define NUSE_MAILBOX_INFORMATION FALSE #define NUSE_MAILBOX_COUNT FALSE
Ошибка времени компиляции приведет к тому, что функция API почтового ящика включена и почтовые ящики не настроены (за исключением NUSE_Mailbox_Count () что всегда разрешено). Если в вашем коде используется вызов API, который не был включен, возникнет ошибка времени связывания, поскольку в приложение не будет включен код реализации.
Обращения в службу почтового ящика
Nucleus RTOS поддерживает девять сервисных вызовов, относящихся к почтовым ящикам, которые обеспечивают следующие функции:
-
Отправить сообщение в почтовый ящик. Реализуется с помощью NUSE_Mailbox_Send () в Nucleus SE.
-
Получить сообщение из почтового ящика. Реализуется с помощью NUSE_Mailbox_Receive () в Nucleus SE.
-
Восстановить почтовый ящик до неиспользуемого состояния без приостановки задач (сброса). Реализуется с помощью NUSE_Mailbox_Reset () в Nucleus SE.
-
Предоставляет информацию об указанном почтовом ящике. Реализуется с помощью NUSE_Mailbox_Information () в Nucleus SE.
-
Возвращает количество почтовых ящиков, настроенных (в настоящее время) для приложения. Реализуется с помощью NUSE_Mailbox_Count () в Nucleus SE.
-
Добавить новый почтовый ящик в приложение (создать). Не реализовано в Nucleus SE.
-
Удалить почтовый ящик из приложения (удалить). Не реализовано в Nucleus SE.
-
Возвращает указатели на все почтовые ящики (в настоящее время) в приложении. Не реализовано в Nucleus SE.
-
Отправить сообщение всем задачам, которые приостановлены в почтовом ящике (широковещательная рассылка). Не реализовано в Nucleus SE.
Подробно рассматривается реализация каждого из этих сервисных вызовов.
Службы записи и чтения почтового ящика
Основные операции, которые могут выполняться с почтовым ящиком, - это запись в него данных, что иногда называют отправкой . или публикация - и чтение данных из него, что также называется получением . Nucleus RTOS и Nucleus SE предоставляют по два основных вызова API для этих операций, которые будут обсуждаться здесь.
Запись в почтовый ящик
Вызов Nucleus RTOS API для записи в почтовый ящик очень гибок, позволяя приостанавливать работу на неопределенный срок или с тайм-аутом, если операция не может быть завершена немедленно; т.е. вы пытаетесь писать на полный почтовый ящик. Nucleus SE предоставляет ту же услугу, за исключением того, что приостановка задачи является необязательной, а тайм-аут не реализуется.
Nucleus RTOS также предлагает возможность широковещательной рассылки в почтовый ящик, но Nucleus SE не поддерживает это. Он будет описан в разделе Нереализованные API . в следующей статье.
Вызов API Nucleus RTOS для отправки в почтовый ящик
Прототип сервисного вызова:
<цитата>STATUS NU_Send_To_Mailbox (NU_MAILBOX * почтовый ящик, VOID * сообщение, НЕПОДПИСАННАЯ приостановка);
Параметры:
<цитата>почтовый ящик - указатель на почтовый ящик, который будет использоваться
сообщение - указатель на отправляемое сообщение, состоящий из четырех беззнаковых элементы
приостановить - спецификация приостановки задания; может быть NU_NO_SUSPEND или NU_SUSPEND или значение тайм-аута
Возврат:
<цитата>NU_SUCCESS - звонок был успешно завершен
NU_INVALID_MAILBOX - указатель почтового ящика недействителен
NU_INVALID_POINTER - указатель сообщения равен NULL
NU_INVALID_SUSPEND - приостановка была предпринята из потока, не связанного с задачей
NU_MAILBOX_FULL - почтовый ящик заполнен и приостановка не указана
NU_TIMEOUT - почтовый ящик все еще заполнен даже после приостановки на указанный период
NU_MAILBOX_DELETED - почтовый ящик был удален, пока задача была приостановлена
NU_MAILBOX_WAS_RESET - почтовый ящик был сброшен, пока задача была приостановлена
Вызов Nucleus SE API для отправки в почтовый ящик
Этот вызов API поддерживает ключевые функции Nucleus RTOS API.
Прототип сервисного вызова:
<цитата>STATUS NUSE_Mailbox_Send (почтовый ящик NUSE_MAILBOX, сообщение ADDR *, U8 приостановить);
Параметры:
<цитата>почтовый ящик - индекс (ID) почтового ящика, который будет использоваться
сообщение - указатель на отправляемое сообщение, представляющий собой единственную переменную типа ADDR .
приостановить - спецификация приостановки задания; может быть NUSE_NO_SUSPEND или NUSE_SUSPEND
Возврат:
<цитата>NUSE_SUCCESS - звонок был успешно завершен
NUSE_INVALID_MAILBOX - индекс почтового ящика недействителен
NUSE_INVALID_POINTER - указатель сообщения равен NULL
NUSE_INVALID_SUSPEND - приостановка была предпринята из потока, не связанного с задачей, или когда блокирование вызовов API не было включено
NUSE_MAILBOX_FULL - почтовый ящик заполнен и приостановка не указана
NUSE_MAILBOX_WAS_RESET - почтовый ящик был сброшен, пока задача была приостановлена
Реализация функции отправки из почтового ящика в Nucleus SE
Основная часть кода NUSE_Mailbox_Send () Функция API - после проверки параметров - выбирается условной компиляцией в зависимости от того, включена ли поддержка блокировки (приостановки задачи) вызовов API. Здесь мы рассмотрим эти два варианта по отдельности.
Если блокировка не включена, логика этого вызова API довольно проста, и код не требует особых пояснений:
if (NUSE_Mailbox_Status [mailbox]) / * почтовый ящик заполнен * / {return_value =NUSE_MAILBOX_FULL;} else / * почтовый ящик пуст * / {NUSE_Mailbox_Data [mailbox] =* message; NUSE_Mailbox_Status [почтовый ящик] =ИСТИНА; return_value =NUSE_SUCCESS;}
Сообщение сохраняется в соответствующем элементе NUSE_Mailbox_Data [] . и почтовый ящик, помеченный как используемый.
Когда блокировка включена, код становится более сложным:
do {if (! NUSE_Mailbox_Status [mailbox]) / * почтовый ящик пуст * / {NUSE_Mailbox_Data [mailbox] =* message; NUSE_Mailbox_Status [почтовый ящик] =ИСТИНА; if (NUSE_Mailbox_Blocking_Count [почтовый ящик]! =0) {индекс U8; / * проверяем, заблокирована ли задача * / / * на этом почтовом ящике * / NUSE_Mailbox_Blocking_Count [mailbox] -; для (index =0; indexНекоторые пояснения могут быть полезны:
Код заключен в делать… пока цикл, который продолжается, пока параметр приостановить имеет значение NUSE_SUSPEND .
Если почтовый ящик пуст, предоставленное сообщение сохраняется, а статус почтового ящика изменяется, показывая, что он заполнен. Проверяется, приостановлены ли (ожидают получения) какие-либо задачи в почтовом ящике. Если есть какие-то задачи, которые ждут, просыпается первая. Приостановить переменная установлена в NUSE_NO_SUSPEND и вызов API завершается с помощью NUSE_SUCCESS .
Если почтовый ящик заполнен и приостановить установлен на NUSE_NO_SUSPEND , вызов API завершается с помощью NUSE_MAILBOX_FULL . Если приостановить был установлен на NUSE_SUSPEND , задача приостановлена. При возврате (т.е. когда задача просыпается), если возвращаемое значение - NUSE_SUCCESS , указывая, что задача была разбужена из-за того, что сообщение было прочитано (в отличие от сброса почтового ящика), код возвращается к началу.
Встроенный
- Введение в кулачковые замки и принцип их работы
- Введение в глазные винты и принцип их действия
- Введение в люверсы и принципы их работы
- Знакомство с нержавеющей сталью и ее производством
- COVID 19 и облако; COVID 19 и его влияние на бизнес
- Базовый ввод и вывод C#
- Семафоры:служебные службы и структуры данных
- Семафоры:введение и базовые услуги
- Группы флагов событий:служебные службы и структуры данных
- Группы флагов событий:введение и базовые услуги