对ECB的操作一般包括:
* 初始化一个事件控制块 (void OS_EventWaitListInit (OS_EVENT *pevent))
* 使一个任务进入就绪态 (INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk))
* 使一个任务进入等待某事件的状态 (void OS_EventTaskWait (OS_EVENT *pevent))
* 因为等待超时而使一个任务进入就绪态 (void OS_EventTO (OS_EVENT *pevent))
对OS_EventTaskRdy()函数和OS_EventTO函数的调用都需要关中断。
1. OS_EventWaitListInit (OS_EVENT *pevent)
此函数被与ECB建立相关的函数调用,如OSSemCreate()、OSMutexCreate()、OSQCreate()和OSMboxCreate()。函数功能就是对ECB中的等待任务列表进行初始化,函数创建时,等待任务列表初始化为空。这个函数是对内的,即此函数可以被uC/OS II调用,用户应用程序不可以直接调用此函数。代码如下:
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)
void OS_EventWaitListInit (OS_EVENT *pevent)
{
INT8U *ptbl;
pevent->OSEventGrp = 0x00;
ptbl = &pevent->OSEventTbl[0];
#if OS_EVENT_TBL_SIZE > 0
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 1
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 2
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 3
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 4
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 5
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 6
*ptbl++ = 0x00;
#endif
#if OS_EVENT_TBL_SIZE > 7
*ptbl = 0x00;
#endif
}
#endif
上面的代码功能比较简单,唯一需要注意的是,Labrosse先生使用条件编译代替了for循环,这样做的目的是减少编译时间(具体的效率,暂不清楚)。
2. INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)
当某事件发生时,要将等待该事件任务列表中优先级最高的的任务置于就绪态,信号量、互斥型信号量、消息邮箱、消息队列所对应的POST函数都会调用OS_EventTaskRdy()。这个函数是对内的,即此函数可以被uC/OS II调用,用户应用程序不可以直接调用此函数。源码如下:
#if OS_EVENT_EN > 0
INT8U OS_EventTaskRdy (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) == 0x00) {
pevent->OSEventGrp &= ~bity;
}
ptcb = OSTCBPrioTbl[prio];
ptcb->OSTCBDly = 0;
ptcb->OSTCBEventPtr = (OS_EVENT *)0;
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
ptcb->OSTCBMsg = msg;
#else
msg = msg;
#endif
ptcb->OSTCBStat &= ~msk;