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

Семафоры в Nucleus SE: Обзор, конфигурация и основы API

Семафоры в Nucleus SE: Обзор, конфигурация и основы API
View the RTOS Revealed series

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

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

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

Семафор — просто 8-битный счетчик, значение которого защищено так, что множественные задачи могут манипулировать им безопасно. Задачи вызывают Obtain для декремента счетчика и Release для инкремента. Если задача пытается получить семафор, чей счетчик ноль, результат зависит от опций API и системной конфигурации: вызов может вернуть ошибку или приостановить задачу до доступности семафора.

Конфигурация семафоров

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

Семафоры определяются через #define директивы в nuse_config.h. Ключевой макрос — NUSE_SEMAPHORE_NUMBER, указывающий, сколько слотов семафоров приложение будет использовать. Значение по умолчанию 0, означающее отсутствие поддержки семафоров. Допустимые значения от 0 до 16. Недействительное значение триггерит compile-time ошибку, генерируемую nuse_config_check.h (включаемую через nuse_config.c).

Установка NUSE_SEMAPHORE_NUMBER в ненулевое значение активирует семафорную подсистему: структуры данных размерятся соответственно, и обрабатываются символы включения API.

API Enables

Каждый Nucleus SE API вызов охраняется выделенным enabling макросом в nuse_config.h. Для семафоров релевантные символы:

По умолчанию все эти макросы установлены в FALSE, что отключает соответствующие service calls и исключает их реализацию из сборки. Для включения конкретного API установите его макрос в TRUE.

Ниже фрагмент из дефолтного nuse_config.h файла:

#define NUSE_SEMAPHORE_NUMBER 0 /* Number of semaphores in the system – 0‑16 */ #define NUSE_SEMAPHORE_OBTAIN FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_RELEASE FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_RESET FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_INFORMATION FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_COUNT FALSE /* Service call enabler */

Включение API вызова без конфигурированных семафоров (кроме NUSE_Semaphore_Count(), который всегда доступен) приводит к compile-time ошибке. Если вы вызываете API, который не был включен, происходит link-time ошибка, потому что реализация опущена.

Semaphore Service Calls

Nucleus SE предлагает восемь семафор-связанных service calls. Первые пять полностью реализованы; оставшиеся три — плейсхолдеры для будущих расширений.

Операции Obtain и Release

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

Nucleus RTOS Obtain API

Прототип:

STATUS NU_Obtain_Semaphore(NU_SEMAPHORE *semaphore, UNSIGNED suspend);

Параметры:

semaphore — указатель на семафор control block.

suspend — может быть NU_NO_SUSPEND, NU_SUSPEND или значение таймаута.

Возвращаемые значения:

NU_SUCCESS — операция успешна.

NU_UNAVAILABLE — значение семафора было нулем.

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

NU_INVALID_SUSPEND — приостановка из non-task контекста.

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

Nucleus SE Obtain API

Прототип:

STATUS NUSE_Semaphore_Obtain(NUSE_SEMAPHORE semaphore, U8 suspend);

Параметры:

semaphore — индекс семафора.

suspend — может быть NUSE_NO_SUSPEND или NUSE_SUSPEND.

Возвращаемые значения:

NUSE_SUCCESS — операция успешна.

NUSE_UNAVAILABLE — значение семафора было нулем.

NUSE_INVALID_SEMAPHORE — недействительный индекс семафора.

NUSE_INVALID_SUSPEND — приостановка из non-task или blocking APIs отключены.

NUSE_SEMAPHORE_WAS_RESET — семафор сброшен во время приостановки.

Implementation Highlights

Когда блокировка отключена, реализация просто проверяет, ненулевой ли счетчик, декрементирует его и возвращает NUSE_SUCCESS. Если счетчик ноль, возвращает NUSE_UNAVAILABLE.

if (NUSE_Semaphore_Counter[semaphore] != 0) { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; } else { return_value = NUSE_UNAVAILABLE; }
Когда блокировка включена, рутина входит в do…while цикл, пытающийся получить семафор. Если счетчик ноль и suspend это NUSE_SUSPEND, задача блокируется. При освобождении первая ожидающая задача пробуждается и цикл повторяет попытку получения.
do { if (NUSE_Semaphore_Counter[semaphore] != 0) { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } else { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_UNAVAILABLE; } else { NUSE_Semaphore_Blocking_Count[semaphore]++; NUSE_Suspend_Task(NUSE_Task_Active, semaphore << 4 | NUSE_SEMAPHORE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } } while (suspend == NUSE_SUSPEND);

Nucleus RTOS Release API

Прототип:

STATUS NU_Release_Semaphore(NU_SEMAPHORE *semaphore);

Параметры:

semaphore — указатель на семафор control block.

Возвращаемые значения:

NU_SUCCESS — операция успешна.

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

Nucleus SE Release API

Прототип:

STATUS NUSE_Semaphore_Release(NUSE_SEMAPHORE semaphore);

Параметры:

semaphore — индекс семафора.

Возвращаемые значения:

NUSE_SUCCESS — операция успешна.

NUSE_INVALID_SEMAPHORE — недействительный индекс семафора.

NUSE_UNAVAILABLE — счетчик уже на 255; не может инкрементировать.

Implementation Highlights

Release рутина сначала проверяет, что счетчик ниже максимума (255). Если так, инкрементирует счетчик. Если блокировка включена и есть задачи, ожидающие на этом семафоре, первая пробуждается.

NUSE_CS_Enter(); if (NUSE_Semaphore_Counter[semaphore] < 255) { NUSE_Semaphore_Counter[semaphore]++; return_value = NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { NUSE_Semaphore_Blocking_Count[semaphore]--; for (U8 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_SUCCESS; NUSE_Wake_Task(index); break; } } } #endif } else { return_value = NUSE_UNAVAILABLE; } NUSE_CS_Exit(); return return_value;

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

Следующая статья исследует event flag groups и их связанные структуры данных.


Колин Уоллс имеет более тридцати лет опыта в электронной индустрии, в основном фокусируясь на embedded software. Он часто выступает на конференциях, пишет технические статьи и автор двух книг по embedded software. Колин — embedded software technologist в Mentor Embedded (Mentor Graphics Embedded Software Division) и базируется в UK. Его блог на https://blogs.mentor.com/colinwalls. Свяжитесь по email colin_walls@mentor.com.


Встроенный

  1. Камерные замки (Cam Locks): как они скрыто запирают шкафы
  2. Что такое кольцевые винты (Eye Screws)? Профессиональное руководство по дизайну и применению
  3. Нержавеющая сталь: состав, производство и глобальное влияние
  4. Основы ввода-вывода в C#: Console.WriteLine, ReadLine и форматирование
  5. Автосервисный консультант (Service Writer): роль, обязанности и карьерный путь
  6. Mailboxes в Nucleus SE: Практическое руководство по конфигурации и использованию
  7. Семафоры в Nucleus RTOS: Утилитарные сервисы и структуры данных
  8. Мастерство Event Flag Groups: Утилитарные сервисы и структуры данных в Nucleus RTOS/SE
  9. Event Flag Groups в Nucleus SE: Вводное руководство по конфигурации и использованию API
  10. Queues в Nucleus SE: Введение и основные Service Calls