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

Семафоры:введение и базовые услуги


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

Семафоры были представлены в более ранней статье. Их основное назначение - контроль доступа к ресурсам.

Использование семафоров

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

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

Настройка семафоров

Количество семафоров

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

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

Включает API

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

NUSE_SEMAPHORE_OBTAIN
NUSE_SEMAPHORE_RELEASE
NUSE_SEMAPHORE_RESET
NUSE_SEMAPHORE_INFORMATION
NUSE_SEMAPHORE_COUNT

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

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

 #define NUSE_SEMAPHORE_NUMBER 0 / * Количество семафоров в системе - 0-16 * / #define NUSE_SEMAPHORE_OBTAIN FALSE / * Активатор сервисного вызова * / #define NUSE_SEMAPHORE_RELEASE FALSE / * Сервисный звонок / * / # define NUSE_SEMAPHALES call enabler * / # define NUSE_SEMAPHORE_INFORMATION FALSE / * Service call enabler * / # define NUSE_SEMAPHORE_COUNT FALSE / * Service call enabler * / 

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

Вызовы службы семафоров

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

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

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

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

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

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

  • Добавить новый семафор в приложение (создать). Не реализовано в Nucleus SE.

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

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

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

Службы получения и выпуска семафоров

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

Получение семафора

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

Вызов API Nucleus RTOS для получения семафора

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

STATUS NU_Obtain_Semaphore (NU_SEMAPHORE * семафор,
НЕПОДПИСАННАЯ приостановка);

Параметры:

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

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

Возврат:

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

NU_UNAVAILABLE - семафор имел нулевое значение

NU_INVALID_SEMAPHORE - указатель семафора недействителен

NU_INVALID_SUSPEND - Приостановка была предпринята из-за незадания

NU_SEMAPHORE_WAS_RESET - семафор был сброшен при приостановке задачи

Вызов Nucleus SE API для получения семафора

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

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

STATUS NUSE_Semaphore_Obtain (семафор NUSE_SEMAPHORE,
U8 приостановить);

Параметры:

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

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

Возврат:

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

NUSE_UNAVAILABLE - семафор имел нулевое значение

NUSE_INVALID_SEMAPHORE - указатель семафора недействителен

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

NUSE_SEMAPHORE_WAS_RESET - семафор был сброшен при приостановке задачи

Реализация функции получения семафора в Nucleus SE

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

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

 if (NUSE_Semaphore_Counter [semaphore]! =0) / * семафор доступен * / {NUSE_Semaphore_Counter [семафор] -; return_value =NUSE_SUCCESS;} else / * семафор недоступен * / {return_value =NUSE_UNAVAILABLE;} 

Значение семафора проверяется и, если оно не равно нулю, уменьшается.

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

 do {if (NUSE_Semaphore_Counter [semaphore]! =0) / * семафор доступен * / {NUSE_Semaphore_Counter [семафор] -; return_value =NUSE_SUCCESS; приостановить =NUSE_NO_SUSPEND; } else / * семафор недоступен * / {if (suspend ==NUSE_NO_SUSPEND) {return_value =NUSE_UNAVAILABLE; } else {/ * блокировать задачу * / NUSE_Semaphore_Blocking_Count [семафор] ++; NUSE_Suspend_Task (NUSE_Task_Active, семафор <<4) | NUSE_SEMAPHORE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; если (return_value! =NUSE_SUCCESS) {suspend =NUSE_NO_SUSPEND; }}}} while (suspend ==NUSE_SUSPEND); 

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

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

Если семафор не равен нулю, он уменьшается. Приостановить переменная установлена ​​в NUSE_NO_SUSPEND и вызов API завершается с помощью NUSE_SUCCESS .

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

Освобождение семафора

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

Вызов API Nucleus RTOS для освобождения семафора

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

STATUS NU_Release_Semaphore (NU_SEMAPHORE * семафор);

Параметры:

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

Возврат:

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

NU_INVALID_SEMAPHORE - указатель семафора недействителен

Вызов Nucleus SE API для освобождения семафора

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

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

STATUS NUSE_Semaphore_Release (семафор NUSE_SEMAPHORE);

Параметры:

семафор - индекс (ID) семафора, который будет выпущен

Возврат:

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

NUSE_INVALID_SEMAPHORE - указатель семафора недействителен

NUSE_UNAVAILABLE - семафор имеет значение 255 и не может быть увеличен

Реализация семафора выпуска в Nucleus SE

Исходный код NUSE_Semaphore_Release () Функция API - после проверки параметров - обычная, вне зависимости от того, включена ли блокировка задач. Значение семафора проверяется и, если оно меньше 255, уменьшается.

Дальнейший код выбирается условной компиляцией, если включена поддержка блокировки (приостановки задачи) вызовов API:

 NUSE_CS_Enter (); if (NUSE_Semaphore_Counter [семафор] <255) {NUSE_Semaphore_Counter [семафор] ++; return_value =NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count [семафор]! =0) {индекс U8; / * проверяем, заблокирована ли задача * / / * на этом семафоре * / NUSE_Semaphore_Blocking_Count [semaphore] -; for (index =0; index  

Если какие-либо задачи приостанавливаются на этом семафоре, пробуждается первая.

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


Колин Уоллс имеет более чем тридцатилетний опыт работы в электронной промышленности, в основном посвященный встроенному программному обеспечению. Часто выступает на конференциях и семинарах и является автором множества технических статей и двух книг по встроенному программному обеспечению. Колин является технологом встраиваемого программного обеспечения в Mentor Embedded [подразделение Mentor Graphics Embedded Software Division], базирующееся в Великобритании. Его постоянный блог находится по адресу:http://blogs.mentor.com/colinwalls. С ним можно связаться по электронной почте [email protected]


Встроенный

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