事件标志组:介绍和基本服务
查看 RTOS Revealed 系列
事件标志组在之前的文章中介绍过。在 Nucleus SE 中,它们有点类似于信号,但具有更大的灵活性。它们提供了一种在任务之间传递简单消息的低成本但灵活的方法。
使用事件标志
在 Nucleus SE 中,事件标志是在构建时配置的。一个应用程序最多可以配置 16 个事件标志组。如果未配置事件标志组,则应用程序中不包含属于事件标志组的数据结构或服务调用代码。
事件标志组只是一组 8 个 1 位标志,对这些标志的访问受到控制,以便多个任务可以安全地使用它。一项任务可以设置或清除事件标志的任意组合。另一个任务可以随时读取事件标志组,也可以等待(轮询或暂停)特定模式的标志。
配置事件标志组
事件标志组的数量
与 Nucleus SE 的大多数方面一样,事件标志组的配置主要由 #define 控制 nuse_config.h 中的语句 .关键设置是 NUSE_EVENT_GROUP_NUMBER ,这决定了为应用程序配置了多少事件标志组。默认设置为 0(即未使用事件标志组),您可以将其设置为最多 16 的任何值。错误的值将导致编译时错误,这是由 nuse_config_check 中的测试生成的。 (这包含在 nuse_config.c 中 因此使用此模块编译)导致 #error 正在编译的语句。
选择非零值是事件标志组的“主启用”。这会导致一些数据结构被相应地定义和调整大小,本系列稍后会详细介绍。它还激活 API 启用设置。
API 启用
Nucleus SE 中的每个 API 函数(服务调用)都有一个启用 #define nuse_config.h 中的符号 .对于事件标志组,这些是:
NUSE_EVENT_GROUP_SET NUSE_EVENT_GROUP_RETRIEVE NUSE_EVENT_GROUP_INFORMATION NUSE_EVENT_GROUP_COUNT
默认情况下,所有这些都设置为 FALSE ,从而禁用每个服务调用并禁止包含任何实现代码。要为应用程序配置事件标志组,您需要选择要使用的 API 调用并将其启用符号设置为 TRUE .
这是默认 nuse_config.h 的摘录 文件。
#define NUSE_EVENT_GROUP_NUMBER 0 /* 事件组数 在系统中 - 0-16 */ #define NUSE_EVENT_GROUP_SET FALSE /* 服务调用启动器 */ #define NUSE_EVENT_GROUP_RETRIEVE FALSE /* 服务调用启动器 */ #define NUSE_EVENT_GROUP_INFORMATION FALSE /* 服务调用启动器 */ #define NUSE_EVENT_GROUP_COUNT FALSE /* 服务调用启动器 */
如果启用了事件标志组 API 功能并且未配置事件标志组(NUSE_Event_Group_Count() 除外),则会导致编译时错误 这总是被允许的)。如果您的代码使用未启用的 API 调用,则会导致链接时间错误,因为应用程序中不会包含任何实现代码。
事件标志服务调用
Nucleus RTOS 支持七个与事件标志相关的服务调用,提供以下功能:
设置事件标志。由 NUSE_Event_Group_Set() 实现 在 Nucleus SE 中。
检索事件标志。由 NUSE_Event_Group_Retrieve() 实现 在 Nucleus SE 中。
提供有关指定事件标志组的信息。由 NUSE_Event_Group_Information() 实现 在 Nucleus SE 中。
返回为应用程序(当前)配置了多少事件标志组的计数。由 NUSE_Event_Group_Count() 实现 在 Nucleus SE 中。
向应用程序添加一个新的事件标志组(创建)。未在 Nucleus SE 中实现。
从应用程序中移除一个事件标志组(删除)。未在 Nucleus SE 中实现。
返回指向应用程序中所有事件标志组(当前)的指针。未在 Nucleus SE 中实现。
详细检查了每个服务调用的实现。
可能需要注意的是,没有提供重置功能(在 Nucleus RTOS 或 Nucleus SE 中)。这是故意的。重置意味着存在特殊条件。对于事件标志组,唯一的“特殊”条件是全零,这可以通过 NUSE_Event_Group_Set() 设置 .
事件标志组设置和检索服务
可以对事件标志组执行的基本操作是设置一个或多个标志并检索标志的当前状态。 Nucleus RTOS 和 Nucleus SE 分别为这些操作提供了两个基本的 API 调用,这里将对其进行讨论。
由于事件标志是位,因此最好将它们可视化为二进制数。由于标准 C 不支持二进制常量的表示(仅八进制和十六进制),Nucleus SE 发行版包含一个有用的头文件 - nuse_binary.h – 包含 #define b01010101 形式的符号 对于所有 256 个 8 位值。
设置事件标志
用于设置事件标志的 Nucleus RTOS API 调用非常灵活,使您能够使用 AND 设置和清除事件标志 和或 操作。 Nucleus SE 提供相同的服务,只是任务挂起是可选的。
用于标志设置的 Nucleus RTOS API 调用
服务调用原型:
STATUS NU_Set_Events(NU_EVENT_GROUP *group, UNSIGNED event_flags,
选项操作);
参数:
组 – 指向用户提供的事件标志组控制块的指针
事件标志 – 要操作的标志模式的位值
操作 – 要执行的操作;可能是 NU_OR (设置标志)或 NU_AND (清除标志)
退货:
NU_SUCCESS – 通话成功
NU_INVALID_GROUP – 事件标志组指针无效
NU_INVALID_OPERATION – 指定的操作不是 NU_OR 或 NU_AND
用于标志设置的 Nucleus SE API 调用
此 API 调用支持 Nucleus RTOS API 的关键功能。
服务调用原型:
STATUS NUSE_Event_Group_Set(NUSE_EVENT_GROUP 组,
U8 event_flags, OPTION操作);
参数:
组 – 要设置/清除标志的事件组的索引 (ID)
事件标志 – 要操作的标志模式的位值
操作 – 要执行的操作;可能是 NUSE_OR (设置标志)或 NUSE_AND (清除标志)
退货:
NUSE_SUCCESS – 通话成功
NUSE_INVALID_GROUP – 事件标志组索引无效
NUSE_INVALID_OPERATION – 指定的操作不是 NUSE_OR 或 NUSE_AND
设置事件标志的 Nucleus SE 实现
NUSE_Event_Group_Set() 的初始代码 API 函数 - 参数检查后 - 很常见,无论是否启用对阻塞(任务挂起)API 调用的支持。逻辑很简单:
NUSE_CS_Enter();if (operation ==NUSE_OR){ NUSE_Event_Group_Data[group] |=event_flags;}else /* NUSE_AND */{ NUSE_Event_Group_Data[group] &=event_flags;}
位模式,event_flags , 只是 ORed 或 ANDed 到指定的事件标志组中。
其余代码仅在启用任务阻塞时才包含:
#if NUSE_BLOCKING_ENABLE while (NUSE_Event_Group_Blocking_Count[group] !=0) { U8索引; /* 检查是否有任务被阻塞 */ /* 在这个事件组 */ for (index=0; index{ if ((LONIB(NUSE_Task_Status[index]) == NUSE_EVENT_SUSPEND) &&(HINIB(NUSE_Task_Status[index]) ==group)) { NUSE_Task_Blocking_Return[index] =NUSE_SUCCESS; NUSE_Task_Status[index] =NUSE_READY; 中断; } } NUSE_Event_Group_Blocking_Count[组]--; } #if NUSE_SCHEDULER_TYPE ==NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif #endif NUSE_CS_Exit(); 返回 NUSE_SUCCESS;
如果任何任务在此事件标志组上挂起(从中检索),它们将全部恢复。当他们有机会执行时,这取决于调度程序,他们可以确定是否满足他们的返回条件 - 请参阅检索事件标志
继续第二页>>
嵌入式