一。 事件控制块ECB数据结构:
typedef struct
{
INT8U OSEventType; //事件类型
INT8U OSEventGrp; //等待任务所在的组
INT16U OSEventCnt; //当事件是信号量时的计数器
void *OSEventPtr; //指向消息或消息队列的指针
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; //等待任务列表
} OS_EVENT;
二.关键算法:
1、将一个任务插入到等待事件的任务列表中:
当调用函数OS_EventTaskWait( )使一个任务进入等待某事件发生时,需要此算法,从而将任务插入到等待事件的任务列表中。
pevent -》 OSEventGrp |= OSMapTbl[prio 》》 3];
pevent -》 OSEventTbl[prio》》3] = OSMapTbl[prio & 0x07];
2、从等待事件的任务列表中使任务脱离等待状态:
当调用函数OS_EventTaskRdy( )使一个任务进入就绪态时,需要调用此算法,从而使等待的任务脱离等待状态进入就绪。
if ((pevent -》 OSEventTbl[prio 》》3] &= ~OSMapTbl[prio & 0x07]) == 0)
{
pevent -》 OSEventGrp &= ~OSMapTbl[prio 》》3];
}
3、在等待事件的任务列表中查找优先级最高的任务:
当调用函数OS_EventTaskRdy( )使一个任务进入就绪态时,需要调用此算法,从而首先找出在等待事件任务列表中最高优先级的任务进入就绪状态。
y = OSUnMapTbl[pevent -》 OSEventGrp];
x = OSUnMapTbl[pevent -》 OSEventTbl[y];
prio = (y 《《 3) + x;
三.对事件控制块ECB的基本操作
1、初始化一个事件控制块:
函数OSSemCreate( ),OSMutexCreate( ),OSMboxCreate( ),OSQCreate( )建立时,必须调用此函数进行初始化,初始化一个空的等待列表,表中没有任何等待事件的任务。
OS_EventWaitListInit( );
2、使一个任务进入就绪态:
当某个事件发生了时,要将事件等待任务列表中最高优先级的任务进入就绪态,函数OSSemPost,OSMutexPost( ),OSMboxPost( ),OSQPost( )必将调用此函数从而使一个任务进入就绪态。
OS_EventTaskRdy( );
3、使一个任务进入等待某事件发生:
当某个任务须等待一个事件的发生时,信号量、互斥型信号量、邮箱、消息队列会通过相应的PEND函数来调用这个函数。
OS_EventTaskWait( );
4、由于等待超时而将任务置为就绪态:
如果在预先指定的等待时间内任务等待的事件没有发生,那么PNED类型函数将会调用此函数从而将等待超时的任务进入就绪态。
OS_EventTo( );
四.事件控制块ECB基本操作代码的分析。
1、OS_EventWaitListInit( );
void OS_EventWaitListInit(OS_EVENT *pevent)
{
INT8U *ptbl; //定义指针变量ptbl
pevent -》 OSEventGrp = 0x00; //清除任务所在的组
OS_EVENT_TBL_SIZE在UCOS_ II.H中定义大小
ptbl = &pevent -》 OSEventTbl[0];
#if OS_EVENT_TBL_SIZE 》 0
*ptbl++ = 0x00; //清除等待任务列表,在这里没有使用for循环是为了节省系统开销
#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
}
2、OS_EventTaskRdy( );
INT8U OS_EventTaskRdy(OS_EVENT *pevent, void *msg,INT8U msk)
{
OS_TCB *ptcb;
INT8U x;
INT8U y;
按照关键算法3,在等待事件的任务列表中找到优先级最高的任务,并确定其优先级。