Семафоры в Nucleus RTOS: Утилитарные сервисы и структуры данных
View the RTOS Revealed series
Эта статья продолжает рассмотрение семафоров.
Semaphore Utility Services
Nucleus RTOS предлагает четыре API вызова, предоставляющие необходимые утилиты для управления семафорами: сброс семафора, получение детальной информации о семафоре, подсчет общего числа семафоров в приложении и получение указателей на все объекты семафоров. Первые три функции полностью реализованы в Nucleus SE.
Сброс семафора
В отличие от большинства kernel объектов, сброс семафора восстанавливает его к указанному начальному счету, а не просто реинициализирует к compile-time значению. Любые задачи, заблокированные на семафоре, немедленно пробуждаются и получают код возврата NUSE_SEMAPHORE_WAS_RESET (или NU_SEMAPHORE_RESET в Nucleus RTOS).
Nucleus RTOS API Call для сброса семафора
Прототип service call:
STATUS NU_Reset_Semaphore(NU_SEMAPHORE *semaphore,
UNSIGNED initial_count);
Параметры:
semaphore — указатель на семафор control block, предоставленный пользователем.
initial_count — значение, к которому должен быть установлен счетчик семафора.
Возвращает:
NU_SUCCESS — операция завершена успешно.
NU_INVALID_SEMAPHORE — указатель семафора недействителен.
Nucleus SE API Call для сброса семафора
Прототип service call:
STATUS NUSE_Semaphore_Reset(NUSE_SEMAPHORE semaphore,
U8 initial_count);
Параметры:
semaphore — индекс (ID) семафора для сброса.
initial_count — значение, к которому должен быть установлен счетчик семафора.
Возвращает:
NUSE_SUCCESS — операция завершена успешно.
NUSE_INVALID_SEMAPHORE — индекс семафора недействителен.
Nucleus SE Реализация сброса семафора
Рутина NUSE_Semaphore_Reset() валидирует свои аргументы и затем записывает новый счет в массив NUSE_Semaphore_Counter[]. Когда блокировка включена, она проходит через таблицу задач для локации любых задач, приостановленных на семафоре, помечает их как ready, присваивает NUSE_SEMAPHORE_WAS_RESET код возврата и наконец триггерит reschedule если активен priority scheduler.
while (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; for (index = 0; index < NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { NUSE_Task_Blocking_Return[index] = NUSE_SEMAPHORE_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Semaphore_Blocking_Count[semaphore]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif
Все приостановленные задачи таким образом переводятся в ready состояние с соответствующим кодом возврата. Если активен priority scheduler, NUSE_Reschedule() обеспечивает, что higher-priority задачи могут преемптить lower-priority.
Информация о семафоре
Этот service call извлекает ключевые детали о семафоре. В Nucleus SE возвращается меньше полей, потому что object naming, suspend ordering и task suspend могут не поддерживаться.
Nucleus RTOS API Call для информации о семафоре
Прототип service call:
STATUS NU_Semaphore_Information(NU_SEMAPHORE *semaphore,
CHAR *name, UNSIGNED *current_count, OPTION *suspend_type,
UNSIGNED *tasks_waiting, NU_TASK **first_task);
Параметры:
semaphore — указатель на запрошенный семафор control block.
name — destination buffer для имени семафора (8 символов плюс null terminator).
current_count — получает текущее значение счетчика семафора.
suspend_type — получает suspend policy (например, NU_FIFO или NU_PRIORITY).
tasks_waiting — получает число задач, приостановленных на семафоре.
first_task — получает указатель на control block первой приостановленной задачи.
Возвращает:
NU_SUCCESS — вызов завершен успешно.
NU_INVALID_SEMAPHORE — указатель семафора недействителен.
Nucleus SE API Call для информации о семафоре
Прототип service call:
STATUS NUSE_Semaphore_Information(NUSE_SEMAPHORE semaphore,
U8 *current_count, U8 *tasks_waiting, NUSE_TASK *first_task);
Параметры:
semaphore — индекс семафора.
current_count — получает текущее значение счетчика.
tasks_waiting — получает число приостановленных задач (если task suspend включен).
first_task — получает индекс первой приостановленной задачи (если task suspend включен).
Возвращает:
NUSE_SUCCESS — вызов завершен успешно.
NUSE_INVALID_SEMAPHORE — индекс семафора недействителен.
NUSE_INVALID_POINTER — один или более указателей аргументов недействительны.
Nucleus SE Реализация информации о семафоре
Реализация лаконична: она входит в critical section, копирует значение счетчика, и если блокировка включена, перечисляет таблицу задач для подсчета ожидающих задач и идентификации первой приостановленной задачи. Иначе waiting count и first task устанавливаются в ноль.
NUSE_CS_Enter(); *current_count = NUSE_Semaphore_Counter[semaphore]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Semaphore_Blocking_Count[semaphore]; if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; for (index = 0; index < NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif NUSE_CS_Exit(); return NUSE_SUCCESS;
Получение числа семафоров
Этот сервис возвращает общее количество семафоров, определенных в приложении. В Nucleus RTOS значение может меняться во время выполнения; в Nucleus SE оно фиксировано на этапе сборки.
Nucleus RTOS API Call для подсчета семафоров
Прототип service call:
UNSIGNED NU_Established_Semaphores(VOID);
Возвращает:
Число семафоров, созданных в приложении.
Nucleus SE API Call для подсчета семафоров
Прототип service call:
U8 NUSE_Semaphore_Count(void);
Возвращает:
Число семафоров, сконфигурированных в приложении.
Nucleus SE Реализация подсчета семафоров
Рутина просто возвращает значение compile-time константы NUSE_SEMAPHORE_NUMBER.
Продолжить на страницу два: "Data Structures" >>
Встроенный
- Облако против собственных серверов: как выбрать правильное хостинг-решение
- Microsoft Azure анонсирует токенизацию блокчейна и сервисы управления данными
- Основы цифровой памяти: адресация, доступ и волатильность
- Мастерство C# переменных и примитивных типов данных: полное руководство
- Структуры C++ против классов: практическое руководство для разработчиков встроенных систем
- Mailboxes в Nucleus SE: Практическое руководство по конфигурации и использованию
- Семафоры в Nucleus SE: Обзор, конфигурация и основы API
- Мастерство Event Flag Groups: Утилитарные сервисы и структуры данных в Nucleus RTOS/SE
- Event Flag Groups в Nucleus SE: Вводное руководство по конфигурации и использованию API
- Queues в Nucleus SE: Введение и основные Service Calls