在完成就绪表和TCB空链表的初始化之后,系统机型ECB事件控制块链表的初始化
- /*
- *********************************************************************************************************
- * INITIALIZATION
- * INITIALIZE THE FREE LIST OF EVENT CONTROL BLOCKS
- *
- * Description: This function is called by OSInit() to initialize the free list of event control blocks.
- *
- * Arguments : none
- *
- * Returns : none
- *********************************************************************************************************
- */
- static void OS_InitEventList (void)
- {
- #if OS_EVENT_EN && (OS_MAX_EVENTS > 0)
- #if (OS_MAX_EVENTS > 1)
- INT16U i;
- OS_EVENT *pevent1;
- OS_EVENT *pevent2;
- OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table */
- pevent1 = &OSEventTbl[0];
- pevent2 = &OSEventTbl[1];
- for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { /* Init. list of free EVENT control blocks */
- pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
- pevent1->OSEventPtr = pevent2;
- #if OS_EVENT_NAME_SIZE > 1
- pevent1->OSEventName[0] = '?'; /* Unknown name */
- pevent1->OSEventName[1] = OS_ASCII_NUL;
- #endif
- pevent1++;
- pevent2++;
- }
- pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
- pevent1->OSEventPtr = (OS_EVENT *)0;
- #if OS_EVENT_NAME_SIZE > 1
- pevent1->OSEventName[0] = '?';
- pevent1->OSEventName[1] = OS_ASCII_NUL;
- #endif
- OSEventFreeList = &OSEventTbl[0];
- #else
- OSEventFreeList = &OSEventTbl[0]; /* Only have ONE event control block */
- OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;
- OSEventFreeList->OSEventPtr = (OS_EVENT *)0;
- #if OS_EVENT_NAME_SIZE > 1
- OSEventFreeList->OSEventName[0] = '?'; /* Unknown name */
- OSEventFreeList->OSEventName[1] = OS_ASCII_NUL;
- #endif
- #endif
- #endif
- }
ECB的主要功能是:一个任务或者一个中断子程序可以通过事件控制块来向另外的任务发出信号,这里所有的信号都被看成是事件,一个任务还可以等待事件的发生,但中断服务子程序是不能等待事件的。
对于事件的等待还可以设定最长等待时间,以避免无限制的等待。
EBC的数据结构为
- /*
- *********************************************************************************************************
- * EVENT CONTROL BLOCK
- *********************************************************************************************************
- */
- #if OS_EVENT_EN && (OS_MAX_EVENTS > 0)
- typedef struct os_event {
- INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_xxxx) */
- void *OSEventPtr; /* Pointer to message or queue structure */
- INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */
- #if OS_LOWEST_PRIO <= 63
- INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
- INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */
- #else
- INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */
- INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */
- #endif
- #if OS_EVENT_NAME_SIZE > 1
- INT8U OSEventName[OS_EVENT_NAME_SIZE];
- #endif
- } OS_EVENT;
- #endif
里面包含的主要数据有
OSEventType:事件的类型
- /*
- *********************************************************************************************************
- * OS_EVENT types
- *********************************************************************************************************
- */
- #define OS_EVENT_TYPE_UNUSED 0u
- #define OS_EVENT_TYPE_MBOX 1u
- #define OS_EVENT_TYPE_Q 2u
- #define OS_EVENT_TYPE_SEM 3u
- #define OS_EVENT_TYPE_MUTEX 4u
- #define OS_EVENT_TYPE_FLAG 5u
- #define OS_TMR_TYPE 100u /* Used to identify Timers ... */
- /* ... (Must be different value than OS_EVENT_TYPE_???) */
有这么几种类型,没有用类型,massage box 类型 消息队列类型 sem信号量类型 和 互斥体和标志位
void *OSEventPtr;指向消息队列或者massage box(邮箱)的无类型指针
INT16U OSEventCnt;信号量计数器,当事件是信号量时有用
INT8U OSEventGrp; OSEventTbl[OS_EVENT_TBL_SIZE];利用字节索引机制;等待列表的优先级选择类似于任务优先级选择列表,由上级8位OSEventGrp;确定头3位,再在列表中查找对应位置1或者清零或者读取
初始化ECB列表OSEventTbl[]利用两个指针和一个for循环将每一个元素设置为type=unused
将name=“?\0” 将OSEventPtr指向下一个元素(ECB)
最后将数组OSEventTbl[]的地址赋值给OSEventFreeList (指向ECB类型的指针!)
最后系统得到的就是OSEventFreeList这样一个指向事件列表的指针
在OS_MAX_EVENTS = 1的情况下只初始化OSEventTbl[0]就可以了。
阅读(2571) | 评论(0) | 转发(0) |