Nucleus RTOS信号量:实用服务与数据结构
查看RTOS Revealed系列
本文继续探讨信号量。
信号量实用服务
Nucleus RTOS提供四个API调用,为信号量管理提供基本实用功能:重置信号量、检索详细信号量信息、统计应用中信号量总数、获取所有信号量对象指针。前三函数在Nucleus SE中完全实现。
重置信号量
与大多数内核对象不同,重置信号量将其恢复到指定初始计数,而非简单重新初始化为编译时值。阻塞在信号量上的任务立即被唤醒,收到返回码NUSE_SEMAPHORE_WAS_RESET(或Nucleus RTOS中的NU_SEMAPHORE_RESET)。
Nucleus RTOS重置信号量API调用
服务调用原型:
STATUS NU_Reset_Semaphore(NU_SEMAPHORE *semaphore,
UNSIGNED initial_count);
参数:
semaphore – 用户提供的信号量控制块指针。
initial_count – 信号量计数器应设定的值。
返回:
NU_SUCCESS – 操作成功完成。
NU_INVALID_SEMAPHORE – 信号量指针无效。
Nucleus SE重置信号量API调用
服务调用原型:
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[]数组。启用阻塞时,遍历任务表定位挂起在该信号量上的任务,标记为就绪,分配NUSE_SEMAPHORE_WAS_RESET返回码,若优先级调度器激活则触发重调度。
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 所有挂起任务因此转为就绪态并带上适当返回码。若优先级调度器激活,NUSE_Reschedule()确保高优先级任务可抢占低优先级任务。
信号量信息
此服务调用检索信号量关键详情。在Nucleus SE中返回字段较少,因对象命名、挂起排序、任务挂起可能不支持。
Nucleus RTOS信号量信息API调用
服务调用原型:
STATUS NU_Semaphore_Information(NU_SEMAPHORE *semaphore,
CHAR *name, UNSIGNED *current_count, OPTION *suspend_type,
UNSIGNED *tasks_waiting, NU_TASK **first_task);
参数:
semaphore – 请求的信号量控制块指针。
name – 信号量名称目标缓冲区(8字符加空终止符)。
current_count – 接收当前信号量计数器值。
suspend_type – 接收挂起策略(如NU_FIFO或NU_PRIORITY)。
tasks_waiting – 接收挂起在该信号量上的任务数。
first_task – 接收首个挂起任务控制块指针。
返回:
NU_SUCCESS – 调用成功完成。
NU_INVALID_SEMAPHORE – 信号量指针无效。
Nucleus SE信号量信息API调用
服务调用原型:
STATUS NUSE_Semaphore_Information(NUSE_SEMAPHORE semaphore,
U8 *current_count, U8 *tasks_waiting, NUSE_TASK *first_task);
参数:
semaphore – 信号量索引。
current_count – 接收当前计数器值。
tasks_waiting – 接收挂起任务数(若任务挂起启用)。
first_task – 接收首个挂起任务索引(若任务挂起启用)。
返回:
NUSE_SUCCESS – 调用成功完成。
NUSE_INVALID_SEMAPHORE – 信号量索引无效。
NUSE_INVALID_POINTER – 一个或多个指针参数无效。
Nucleus SE信号量信息实现
实现简洁:进入临界区,复制计数器值,若阻塞启用则枚举任务表统计等待任务并识别首个挂起任务,否则等待计数和首个任务设为零。
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调用
服务调用原型:
UNSIGNED NU_Established_Semaphores(VOID);
返回:
应用中创建的信号量数量。
Nucleus SE信号量计数API调用
服务调用原型:
U8 NUSE_Semaphore_Count(void);
返回:
应用中配置的信号量数量。
Nucleus SE信号量计数实现
例程仅返回编译时常量NUSE_SEMAPHORE_NUMBER的值。
继续阅读第二页:“数据结构” >>
嵌入式
- 数字存储器基础:寻址、访问与易失性
- C++结构体与类:嵌入式开发者实战指南
- Nucleus SE邮箱:配置与使用实战指南
- Nucleus SE信号量:概览、配置与API要点
- 掌握事件标志组:Nucleus RTOS/SE实用服务与数据结构
- Nucleus SE事件标志组:配置与API使用入门指南
- Nucleus SE队列:介绍与核心服务调用
- Swissbit 在 it-sa 展示面向 IoT 设备的前沿硬件安全方案
- 云托管 vs 自建服务器:如何选择适合的数据托管方案
- Microsoft Azure推出区块链代币化与数据管理服务:重塑数据安全新范式
- 构建负责任可信AI:可解释性、问责制与伦理三大支柱实战指南
- 精通C#变量与基础数据类型:完整指南