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

Nucleus RTOS信号量:实用服务与数据结构

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的值。

继续阅读第二页:“数据结构” >>

嵌入式

  1. 数字存储器基础:寻址、访问与易失性
  2. C++结构体与类:嵌入式开发者实战指南
  3. Nucleus SE邮箱:配置与使用实战指南
  4. Nucleus SE信号量:概览、配置与API要点
  5. 掌握事件标志组:Nucleus RTOS/SE实用服务与数据结构
  6. Nucleus SE事件标志组:配置与API使用入门指南
  7. Nucleus SE队列:介绍与核心服务调用
  8. Swissbit 在 it-sa 展示面向 IoT 设备的前沿硬件安全方案
  9. 云托管 vs 自建服务器:如何选择适合的数据托管方案
  10. Microsoft Azure推出区块链代币化与数据管理服务:重塑数据安全新范式
  11. 构建负责任可信AI:可解释性、问责制与伦理三大支柱实战指南
  12. 精通C#变量与基础数据类型:完整指南