亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial Internet of Things >> 嵌入式

Nucleus SE信号量:概览、配置与API要点

Nucleus SE信号量:概览、配置与API要点
查看RTOS Revealed系列

信号量是嵌入式系统中同步共享资源访问的基础机制。它们允许任务安全获取和释放资源控制权,避免冲突。

使用信号量

在Nucleus SE中,信号量支持在构建过程中启用。单个应用最多可配置16个信号量。若不使用任何信号量,相关数据结构和API代码从最终二进制中排除,减小占用。

信号量本质是受保护的8位计数器,多任务可安全操作。任务调用Obtain递减计数器,调用Release递增。若任务尝试获取计数器为零的信号量,结果取决于API选项和系统配置:调用可能返回错误或挂起任务直至信号量可用。

配置信号量

信号量数量

信号量通过nuse_config.h中#define语句定义。关键宏NUSE_SEMAPHORE_NUMBER指定应用将使用的信号量槽位数。默认值0表示无信号量支持。有效值0到16。无效值触发nuse_config_check.h产生的编译时#error(通过nuse_config.c包含)。

将NUSE_SEMAPHORE_NUMBER设为非零值激活信号量子系统:数据结构相应定尺寸,API启用符号被处理。

API启用

每个Nucleus SE API调用由nuse_config.h中专用启用宏保护。信号量相关符号:

默认全设为FALSE,禁用对应服务调用并从构建中排除实现。启用特定API,将其宏设为TRUE。

以下是默认nuse_config.h文件片段:

#define NUSE_SEMAPHORE_NUMBER 0 /* 系统信号量数量 – 0‑16 */ #define NUSE_SEMAPHORE_OBTAIN FALSE /* 服务调用启用器 */ #define NUSE_SEMAPHORE_RELEASE FALSE /* 服务调用启用器 */ #define NUSE_SEMAPHORE_RESET FALSE /* 服务调用启用器 */ #define NUSE_SEMAPHORE_INFORMATION FALSE /* 服务调用启用器 */ #define NUSE_SEMAPHORE_COUNT FALSE /* 服务调用启用器 */

未配置信号量时启用API调用(除NUSE_Semaphore_Count()始终可用外)导致编译时错误。调用未启用的API因实现被省略导致链接时错误。

信号量服务调用

Nucleus SE提供八个信号量相关服务调用。前五个完全实现;其余三个为未来扩展占位。

获取与释放操作

核心信号量操作是获取(递减)和释放(递增)。Nucleus RTOS提供灵活获取API支持可选挂起和超时。Nucleus SE镜像此行为,但任务挂起可选、不支持超时。

Nucleus RTOS获取API

原型:

STATUS NU_Obtain_Semaphore(NU_SEMAPHORE *semaphore, UNSIGNED suspend);

参数:

semaphore – 信号量控制块指针。

suspend – 可为NU_NO_SUSPEND、NU_SUSPEND或超时值。

返回值:

NU_SUCCESS – 操作成功。

NU_UNAVAILABLE – 信号量值为零。

NU_INVALID_SEMAPHORE – 无效信号量指针。

NU_INVALID_SUSPEND – 非任务上下文尝试挂起。

NU_SEMAPHORE_WAS_RESET – 任务挂起期间信号量被重置。

Nucleus SE获取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 – 非任务上下文或阻塞API禁用时尝试挂起。

NUSE_SEMAPHORE_WAS_RESET – 挂起期间信号量重置。

实现亮点

禁用阻塞时,实现仅检查计数器非零则递减并返回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释放API

原型:

STATUS NU_Release_Semaphore(NU_SEMAPHORE *semaphore);

参数:

semaphore – 信号量控制块指针。

返回值:

NU_SUCCESS – 操作成功。

NU_INVALID_SEMAPHORE – 无效信号量指针。

Nucleus SE释放API

原型:

STATUS NUSE_Semaphore_Release(NUSE_SEMAPHORE semaphore);

参数:

semaphore – 信号量索引。

返回值:

NUSE_SUCCESS – 操作成功。

NUSE_INVALID_SEMAPHORE – 无效信号量索引。

NUSE_UNAVAILABLE – 计数器已达255;无法递增。

实现亮点

释放例程先检查计数器低于最大值(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;

当任务挂起于信号量,释放它会唤醒首个等待任务,使其继续执行。

下一篇将探讨事件标志组及其相关数据结构。


Colin Walls在电子行业拥有三十多年经验,主要专注嵌入式软件。频繁在会议演讲、撰写技术文章,著有两本嵌入式软件书籍。Colin是Mentor Embedded(门托图形嵌入式软件部)嵌入式软件技术专家,驻英国。博客https://blogs.mentor.com/colinwalls。邮件colin_walls@mentor.com联系。

嵌入式

  1. 精密平面磨削服务:微米级平面度与表面质量的专业交付
  2. UCAS 续约 Infosys 三年,自动化应对百万申请者激增
  3. 凸轮锁详解:如何隐蔽锁固柜体
  4. 什么是环眼螺丝?设计与用途专业指南
  5. 不锈钢详解:成分、生产与全球影响
  6. 汽车服务顾问:角色、职责与职业路径
  7. Nucleus SE邮箱:配置与使用实战指南
  8. Nucleus RTOS信号量:实用服务与数据结构
  9. 掌握事件标志组:Nucleus RTOS/SE实用服务与数据结构
  10. Nucleus SE事件标志组:配置与API使用入门指南
  11. Nucleus SE队列:介绍与核心服务调用
  12. C# 基础:输入输出核心技巧完全指南