对UCOSII事件的总结
1、 在ucosii中事件主要有五种
A、信号量 OS_EVENT_TYPE_SEM
B、互斥信号量 OS_EVENT_TYPE_MUTEX
C、消息邮箱 OS_EVENT_TYPE_MBOX
D、消息队列 OS_EVENT_TYPE_Q
E、信号量集 OS_EVNET_TYPE_FLAG
2、事件的结构体。
OS_EVENT_TYPE_SEM OS_EVENT_TYPE_MUTEX OS_EVENT_TYPE_MBOX OS_EVENT_TYPE_Q |
OS_EVNET_TYPE_FLAG | |
OS_FLAG_GRP 信号量级的标志组 | OS_FLAG_NODE 信号量节点 | |
Typedef struct { INT8U OSEventType INT16U OSEventCnt Void *OSEventPtr INT8U OSEventGrp INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; }OS_EVNET | typedef struct os_flag_grp { INT8U OSFlagType; void *OSFlagWaitList; OS_FLAGS OSFlagFlags; #if OS_FLAG_NAME_SIZE > 1 INT8U OSFlagName[OS_FLAG_NAME_SIZE]; #endif } OS_FLAG_GRP; | typedef struct os_flag_node { void *OSFlagNodeNext; void *OSFlagNodePrev; void *OSFlagNodeTCB; void *OSFlagNodeFlagGrp; OS_FLAGS OSFlagNodeFlags; INT8U OSFlagNodeWaitType; } OS_FLAG_NODE; |
3、他们共有的操作
(1)、初始化创建空链表函数
A、信号量,互斥信号量,消息邮箱,消息队列,初始化创建链表,
static void OS_InitEventList (void)
{
INT16U i;
#if (OS_MAX_EVENTS > 1)
OS_EVENT *pevent1;
OS_EVENT *pevent2;
Pevent1 = &OSEventTbl[0];
Pevent2 = &OSEventTdl[1];
OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl))
For(i=0;i<(OS_MAX_EVENTS -1);i++)
{
Pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
Pevent1->OSEventPtr = pevent2;
Peven1++;
Pevent2++;
}
pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent1->OSEventPtr = (OS_EVENT *)0;
OSEventFreeList = &OSEventTbl[0];
#else //整个链表只有一个元素
{
OSEventFreeList = &OSEventTbl[0];
OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;
OSEventFreeList->OSEventPtr = (OS_EVENT *)0;
}
}
其中OSEventType的取值是:
OS_EVENT_TYPE_SEM
OS_EVENT_TYPE_MUTEX
OS_EVENT_TYPE_MBOX
OS_EVENT_TYPE_Q
重点在创建链表的时候一定要注意是:链表头和链表尾的赋值
B、信号量集的初始化
Void OS_FlagInit(void)
{
#if OS_MAX_FLAGS == 1
OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0];
OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED;
OSFlagFreeList->OSFlagWaitList = (void *)0;
OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0;
#if OS_FLAG_NAME_SIZE > 1
OSFlagFreeList->OSFlagName[0] = '?';
OSFlagFreeList->OSFlagName[1] = OS_ASCII_NUL;
#endif
#endif
#if OS_MAX_FLAGS >= 2
INT16U i;
OS_FLAG_GRP *pgrp1;
OS_FLAG_GRP *pgrp2;
OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl));
pgrp1 = &OSFlagTbl[0];
pgrp2 = &OSFlagTbl[1];
for (i = 0; i < (OS_MAX_FLAGS - 1); i++)
{
pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED;
pgrp1->OSFlagWaitList = (void *)pgrp2;
#if OS_FLAG_NAME_SIZE > 1
pgrp1->OSFlagName[0] = '?'; pgrp1->OSFlagName[1] = OS_ASCII_NUL;
#endif
pgrp1++;
pgrp2++;
}
pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED;
pgrp1->OSFlagWaitList = (void *)0;
#if OS_FLAG_NAME_SIZE > 1
pgrp1->OSFlagName[0] = '?';
pgrp1->OSFlagName[1] = OS_ASCII_NUL;
#endif
OSFlagFreeList = &OSFlagTbl[0];
#endif
}
}
建立好的空的链表的格式
重点在创建链表后OSFlagWaitList他最后指向的是等待任务链表的表头OS_FlAG_NODE;
(2)、控制块的初始化函数
A、信号量,互斥信号量,消息邮箱,消息队列,初始化创建链表
#if OS_EVENT_EN
void OS_EventWaitListInit (OS_EVENT *pevent)
{
#if OS_LOWEST_PRIO <= 63
INT8U *ptbl;
#else
INT16U *ptbl;
#endif
INT8U i;
pevent->OSEventGrp = 0;
ptbl = &pevent->OSEventTbl[0];
for (i = 0; i < OS_EVENT_TBL_SIZE; i++)
{
*ptbl++ = 0;
}
}
#endif
与前面的版本相比,这里对OSEventTbl[OS_EVENT_TBL_SIZE]进行的清零的操作,是使用的指针进行操作的,以前就是直接对数组进行赋值。
提问:为什么要对他们进行初始化?
要解决这个问题,
1、OSEventGrp和OSEventTbl[i]有所理解,
OSEventGrp的位置就是i
例如: OSEventGrp= 0001 0000那么对应的I = 4
这就表明在OSEventTbl[4]中有任务处于等待状态。
所以只有在初始化的时候将这两个变量设为0,那么就表示没有任务是等待状态。
2、 为什么不能是等待状态?
在OSXXXPostde 函数中会对使所有的任务进入就绪状态,所以这里也并不一定需要。