Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial Internet of Things >> Встроенный

Очереди:введение и базовые услуги


Посмотреть серию раскрытых ОСРВ

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

Использование очередей

В Nucleus SE очереди настраиваются во время сборки. Для приложения может быть настроено не более 16 очередей. Если очереди не настроены, в приложение не включаются никакие структуры данных или код вызова службы, относящиеся к очередям.

Очередь - это просто набор ячеек хранения, каждое из которых достаточно велико, чтобы вместить один элемент данных типа ADDR . , доступ к которому контролируется, чтобы его можно было безопасно использовать в нескольких задачах. Задачи могут записывать в очередь несколько раз, пока все места не будут заполнены. Задачи могут считываться из очереди, и данные обычно принимаются в порядке очереди (FIFO). Попытка отправить в полную очередь или прочитать из пустой может привести к ошибке или приостановке задачи, в зависимости от параметров, выбранных в вызове API, и конфигурации Nucleus SE.

Очереди и конвейеры

Nucleus SE также поддерживает каналы, которые также были представлены в предыдущей статье и подробно описаны в следующей статье. Основное различие между очередями и каналами - это размер сообщения. Очереди содержат сообщения, содержащие один ADDR . - обычно это указатели. Канал передает сообщения длиной произвольное количество байтов; размер фиксируется для каждой трубы в приложении и устанавливается во время настройки.

Настройка очередей

Количество очередей

Как и в большинстве аспектов Nucleus SE, конфигурация очередей в основном контролируется #define . операторы в nuse_config.h . Ключевой параметр: NUSE_QUEUE_NUMBER . , который определяет, сколько очередей настроено для приложения. По умолчанию установлено значение 0 (т.е. очереди не используются), и вы можете установить для него любое значение до 16. Ошибочное значение приведет к ошибке времени компиляции, которая генерируется тестом в nuse_config_check.h (он включен в nuse_config.c и, следовательно, скомпилирован с этим модулем), что приводит к ошибке #error выписка составляется.

Выбор ненулевого значения является «основным включением» для очередей. Это приводит к тому, что некоторые структуры данных определяются и имеют соответствующий размер, о чем подробнее в следующей статье. Он также активирует настройки включения API.

Включает API

Каждая функция API (вызов службы) в Nucleus SE имеет разрешающий #define символ в nuse_config.h . Для очередей это:

NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_COUNT

По умолчанию все они имеют значение FALSE . , таким образом отключая каждый вызов службы и запрещая включение любого кода реализации. Чтобы настроить очереди для приложения, вам необходимо выбрать вызовы API, которые вы хотите использовать, и установить для их символов включения значение ИСТИНА . .

Вот выдержка из файла nuse_config.h по умолчанию.

#define NUSE_QUEUE_NUMBER 0 / * Количество очередей в
System - 0-16 * /
/ * Активаторы сервисных вызовов * /
#define NUSE_QUEUE_SEND FALSE
#define NUSE_QUEUE_RECEIVE FALSE
#define NUSE_QUEUE_JAM FALSE
#define NUSE_QUEUE_RESET FALSE
#define NUSE_QUEUE_INFORMATION FALSE
#define NUSE_QUEUE_COUNT FALSE

Ошибка времени компиляции произойдет, если функция API очереди включена и очереди не настроены (за исключением NUSE_Queue_Count () что всегда разрешено). Если в вашем коде используется вызов API, который не был включен, возникнет ошибка времени связывания, поскольку в приложение не будет включен код реализации.

Вызовы службы очереди

Nucleus RTOS поддерживает десять сервисных вызовов, относящихся к очередям, которые обеспечивают следующие функции:

  • Отправить сообщение в очередь. Реализуется с помощью NUSE_Queue_Send () в Nucleus SE.

  • Получить сообщение из очереди. Реализуется с помощью NUSE_Queue_Receive () в Nucleus SE.

  • Отправить сообщение в начало очереди. Реализуется с помощью NUSE_Queue_Jam () в Nucleus SE.

  • Восстановить очередь до неиспользуемого состояния без приостановки (сброса) задач. Реализуется с помощью NUSE_Queue_Reset () в Nucleus SE.

  • Предоставляет информацию об указанной очереди. Реализуется с помощью NUSE_Queue_Information () в Nucleus SE.

  • Возвращает количество очередей, настроенных (в настоящее время) для приложения. Реализуется с помощью NUSE_Queue_Count () в Nucleus SE.

  • Добавить новую очередь в приложение (создать). Не реализовано в Nucleus SE.

  • Удалить очередь из приложения (удалить). Не реализовано в Nucleus SE.

  • Возвращает указатели на все очереди (в настоящее время) в приложении. Не реализовано в Nucleus SE.

  • Отправить сообщение всем задачам, которые приостановлены в очереди (широковещательная рассылка). Не реализовано в Nucleus SE.

Подробно рассматривается реализация каждого из этих сервисных вызовов.

Службы записи и чтения очереди

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

Запись в очередь

Вызов API Nucleus RTOS для записи в очередь очень гибок, позволяя приостанавливать работу на неопределенный срок или с тайм-аутом, если операция не может быть завершена немедленно; т.е. вы пытаетесь писать в полную очередь. Nucleus SE предоставляет ту же услугу, за исключением того, что приостановка задачи является необязательной, а тайм-аут не реализуется.

Nucleus RTOS также предлагает возможность широковещательной рассылки в очередь, но это не поддерживается Nucleus SE. Это описано в разделе «Невыполненные API-интерфейсы» следующей статьи.

Вызов API Nucleus RTOS для отправки в очередь

Прототип сервисного вызова:

STATUS NU_Send_To_Queue (NU_QUEUE * очередь, VOID * сообщение,
UNSIGNED размер, UNSIGNED приостановить);

Параметры:

очередь - указатель на пользовательский блок управления очередью

сообщение - указатель на сообщение, которое нужно отправить

размер - количество НЕПОДПИСАННЫХ элементы данных в сообщении. Если очередь поддерживает сообщения переменной длины, этот параметр должен быть равен или меньше размера сообщения, поддерживаемого очередью. Если очередь поддерживает сообщения фиксированного размера, этот параметр должен быть точно таким же, как размер сообщения, поддерживаемый очередью.

приостановить - спецификация приостановки задания; может быть NU_NO_SUSPEND или NU_SUSPEND или значение тайм-аута

Возврат:

NU_SUCCESS - звонок был успешно завершен

NU_INVALID_QUEUE - указатель очереди недействителен

NU_INVALID_POINTER - указатель сообщения NULL

NU_INVALID_SIZE - размер сообщения несовместим с размером сообщения, поддерживаемым очередью

NU_INVALID_SUSPEND - приостановка была предпринята из потока, не связанного с задачей

NU_QUEUE_FULL - очередь заполнена и приостановка не указана

NU_TIMEOUT - очередь все еще заполнена даже после приостановки на указанное значение тайм-аута

NU_QUEUE_DELETED - очередь была удалена, пока задача была приостановлена ​​

NU_QUEUE_RESET - очередь была сброшена, пока задача была приостановлена ​​

Вызов Nucleus SE API для отправки в очередь

Этот вызов API поддерживает ключевые функции Nucleus RTOS API.

Прототип сервисного вызова:

STATUS NUSE_Queue_Send (очередь NUSE_QUEUE, сообщение ADDR *,
приостановка U8);

Параметры:

очередь - индекс (ID) очереди, которая будет использоваться

сообщение - указатель на отправляемое сообщение, представляющий собой единственную переменную типа ADDR .

приостановить - спецификация приостановки задания; может быть NUSE_NO_SUSPEND или NUSE_SUSPEND

Возврат:

NUSE_SUCCESS - звонок был успешно завершен

NUSE_INVALID_QUEUE - указатель очереди недействителен

NUSE_INVALID_POINTER - указатель сообщения NULL

NUSE_INVALID_SUSPEND - приостановка была предпринята из потока, не связанного с задачей, или когда блокирование вызовов API не было включено

NUSE_QUEUE_FULL - очередь заполнена и приостановка не указана

NUSE_QUEUE_WAS_RESET - очередь была сброшена, пока задача была приостановлена ​​

Реализация очереди ASend в Nucleus SE

Основная часть кода NUSE_Queue_Send () Функция API - после проверки параметров - выбирается условной компиляцией в зависимости от того, включена ли поддержка блокировки (приостановки задачи) вызовов API. Здесь мы рассмотрим эти два варианта по отдельности.

Если блокировка не включена, код для этого вызова API довольно прост:

 if (NUSE_Queue_Items [queue] ==NUSE_Queue_Size [queue]) / * очередь заполнена * / {return_value =NUSE_QUEUE_FULL;} else / * доступен элемент очереди * / {NUSE_Queue_Data [queue] [NUSE_Queue_Heue] [NUSE_Queue_Hueue_H *сообщение; если (NUSE_Queue_Head [очередь] ==NUSE_Queue_Size [очередь]) {NUSE_Queue_Head [очередь] =0; } NUSE_Queue_Items [очередь] ++; return_value =NUSE_SUCCESS;} 

Функция просто проверяет, есть ли место в очереди, и использует NUSE_Queue_Head [] index, чтобы сохранить сообщение в области данных очереди.

Когда блокировка включена, код становится более сложным:

 do {if (NUSE_Queue_Items [queue] ==NUSE_Queue_Size [queue]) / * очередь заполнена * / {if (suspend ==NUSE_NO_SUSPEND) {return_value =NUSE_QUEUE_FULL; } else {/ * блокировать задачу * / NUSE_Queue_Blocking_Count [queue] ++; NUSE_Suspend_Task (NUSE_Task_Active, (очередь <<4) | NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; если (return_value! =NUSE_SUCCESS) {suspend =NUSE_NO_SUSPEND; }}} else {/ * доступен элемент очереди * / NUSE_Queue_Data [queue] [NUSE_Queue_Head [queue] ++] =* message; если (NUSE_Queue_Head [очередь] ==NUSE_Queue_Size [очередь]) {NUSE_Queue_Head [очередь] =0; } NUSE_Queue_Items [очередь] ++; if (NUSE_Queue_Blocking_Count [queue]! =0) {индекс U8; / * проверяем, заблокирована ли задача в этой очереди * / NUSE_Queue_Blocking_Count [queue] -; for (index =0; index  

Некоторое объяснение кода может быть полезно:

Код заключен в делать… пока цикл, который продолжается, пока параметр suspend имеет значение NUSE_SUSPEND .

Если очередь заполнена и приостановить установлен на NUSE_NO_SUSPEND , вызов API завершается с NUSE_QUEUE_FULL . Если для приостановки задано значение NUSE_SUSPEND , задача приостановлена. При возврате (т. Е. Когда задача просыпается), если возвращаемое значение - NUSE_SUCCESS , указывая, что задача была разбужена из-за того, что сообщение было прочитано (в отличие от сброса очереди), код возвращается наверх.

Если очередь не заполнена, предоставленное сообщение сохраняется с использованием NUSE_Queue_Head [] index, чтобы сохранить сообщение в области данных очереди. Проверяется, приостановлены (ожидают получения) какие-либо задачи в очереди. Если есть какие-то задачи, которые ждут, просыпается первая. Приостановить переменная установлена ​​в NUSE_NO_SUSPEND и вызов API завершается с помощью NUSE_SUCCESS .


Встроенный

  1. Введение в кулачковые замки и принцип их работы
  2. Введение в глазные винты и принцип их действия
  3. Введение в люверсы и принципы их работы
  4. Знакомство с нержавеющей сталью и ее производством
  5. Базовый ввод и вывод C#
  6. Почтовые ящики:введение и основные услуги
  7. Семафоры:служебные службы и структуры данных
  8. Семафоры:введение и базовые услуги
  9. Группы флагов событий:служебные службы и структуры данных
  10. Группы флагов событий:введение и базовые услуги