任务之间的同步与通信( 三 )


1:事件控制块结构
ECB数据结构如下,与TCB类似的结构,使用两个链表,空闲链表与使用链表 。
typedef struct {void *OSEventPtr; /*指向消息或消息队列的指针*/INT8U OSEventTbl[OS_EVENT_TBL_SIZE];//等待任务列表INT16U OSEventCnt; /*计数器(当事件是信号量时)*/INT8U OSEventType; /*事件类型:信号量、邮箱等*/INT8U OSEventGrp; /*等待任务组*/} OS_EVENT;
每个等待事件发生的任务都被加入到该事件事件控制块中的等待任务列表中,该列表包括. 和.[]两个域 。
所有的任务的优先级被分成 8 组(每组 8 个优先级),分别对应. 中的 8 位,每个优先级就代表着一个任务 。当某组中有任务处于等待该事件的状态时,. 中对应的位就被置位 。相应地,该任务在.[]中的对应位也被置位 。
.[]数组的大小由系统中任务的最低优先级决定,这个值由 .H 中的常数定义 。当一个事件发生后,该事件的等待事件列表中优先级最高的任务,也即在.[]中,所有被置 1 的位中,优先级代码最小的任务得到该事件 。下图给出了.和.[]之间的对应关系 。该关系可以描述为
当.[0]中的任何一位为 1 时,. 中的第 0 位为 1 。
当.[1]中的任何一位为 1 时,. 中的第 1 位为 1 。
当.[2]中的任何一位为 1 时,. 中的第 2 位为 1 。
当.[3]中的任何一位为 1 时,. 中的第 3 位为 1 。
当.[4]中的任何一位为 1 时,. 中的第 4 位为 1 。
当.[5]中的任何一位为 1 时,. 中的第 5 位为 1 。
当.[6]中的任何一位为 1 时,. 中的第 6 位为 1 。
当.[7]中的任何一位为 1 时,. 中的第 7 位为 1 。
2:相关操作函数
在μC/OS-II 中,事件控制块的总数由用户所需要的信号量、邮箱和消息队列的总数决定 。该值由 .H 中的#定义 。在调用 ()时,所有事件控制块被链接成一个单向链表——空闲事件控制块链表,如下图所示 。每当建立一个信号量、邮箱或者消息队列时,就从该链表中取出一个空闲事件控制块,并对它进行初始化 。因为信号量、邮箱和消息队列一旦建立就不能删除,所以事件控制块也不能放回到空闲事件控制块链表中
对于事件控制块进行的一些通用操作包括:
初始化一个事件控制块使一个任务进入就绪态使一个任务进入等待该事件的状态因为等待超时而使一个任务进入就绪态
为了避免代码重复和减短程代码长度,μC/OS-II 将上面的操作用 4 个系统函数实现,它们是:(),(),()和 ()
( *)
初始化一个事件控制块 。当创建一个信号量、邮箱或消息队列时,相应的创建函数会调用本函数对ECB的内容进行初始化,将和[]数组清零;
:指向需要初始化的事件控制块的指针 。
void OSEventWaitListInit (OS_EVENT *pevent){INT8U i;pevent->OSEventGrp = 0x00;for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {pevent->OSEventTbl[i] = 0x00;}}
( *,void *msg, INT8U msk);
使一个任务进入就绪态 。当一个事件发生时,需要将其等待任务列表中的最高优先级任务置为就绪态;
msg:指向消息的指针;msk:用于设置TCB的状态 。
void OSEventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk){OS_TCB *ptcb;INT8U x;INT8U y;INT8U bitx;INT8U bity;INT8U prio;y = OSUnMapTbl[pevent->OSEventGrp];bity = OSMapTbl[y];x = OSUnMapTbl[pevent->OSEventTbl[y]];bitx = OSMapTbl[x];prio = (INT8U)((y << 3) + x);if ((pevent->OSEventTbl[y] &= ~bitx) == 0) {pevent->OSEventGrp &= ~bity;}ptcb = OSTCBPrioTbl[prio];ptcb->OSTCBDly = 0;ptcb->OSTCBEventPtr = (OS_EVENT *)0;#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_ENptcb->OSTCBMsg = msg;#elsemsg = msg;#endifptcb->OSTCBStat &= ~msk;if (ptcb->OSTCBStat == OS_STAT_RDY) {OSRdyGrp |= bity; (13)OSRdyTbl[y] |= bitx;}}