等待任务列表
对于事件来说,当其被占用时,会导致其他请求该事件的任务因暂时得不到该事件的服务而处于等待状态。对于这些等待任务具有两方面的管理功能,一是要对等待事件的所有任务进行记录并排序;二是应该允许等待任务有一个等待时限,即当等待任务认为等不及时可以退出对事件的请求。对于等待事件任务的记录,uC/OS-II又使用了与任务就绪表类似的位图,即定义一个INT8U类型的数组OSEventTbl[]作为等待事件任务的记录表。事件等待任务表类似任务的优先级就绪表操作一样,也定义了一个INT8U的类型变量OSEventGrp来表示等待任务表中的任务组。等待任务表OSEventTbl[]与变量OSEventGrp的示意图如图4-6所示。
图4-6 事件的等待任务表
至于等待任务的等待时限,则记录在等待任务的任务控制块TCB的成员OSTCBDly中,并在每个时钟节拍中断服务程序中对该数据进行维护。
事件控制块的结构
uC/OS-II事件控制块ECB的数据结构如下:
typedef struct {
INT8U OSEventType; //事件的类型
INT8U OSEventCnt; //信号量计数器
INT8U *OSEventPtr; //消息或消息队列的指针
INT8U OSEventGrp; //等待事件的任务组
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; //任务等待表
} OS_EVENT;
事件控制块结构示意图如图4-7所示。
应用程序中的任务通过指针pevent来访问事件控制块。
事件控制块ECB结构中的成员OSEventType用来指明事件的类型。成员OSEventType可能的取值见表4-1。
图4-7 事件控制块ECB结构
表4-1 OSEventType可能的取值
事件控制块函数
事件控制块的初始化函数EventWaitListInit()的原型如下:void OS_EventWaitListInit(
OS_EVENT *pevent //事件控制块的指针
)
事件控制块被初始化后的情况如图4-8所示。
图4-8 初始化后的事件控制块
使一个任务进入等待状态的函数void OS_EventTaskWait(
OS_EVENT *pevent //事件控制块的指针
)
使一个正在等待的任务进入就绪状态的函数void OS_EventTaskRdy(
OS_EVENT *pevent, //事件控制块的指针
void *msg, //未使用
INT8U mask //清除TCB状态标志掩码
);
使一个等待超时的任务进入就绪状态的函数void OS_EventTO(
OS_EVENT *pevnt;
)
空事件控制块链表
系统在初始化函数OSInit()中按应用程序使用事件的总数OS_MAX_EVENTS创建OS_MAX_EVENTS个空事件控制块并借用成员OSEventPtr作为链表指针,把这些空事件连成一个如图4-9 所示的单向链表。
图 4-9 空事件控制块链表