1、任务和任务,任务和中断子程序是如何进行通信的
事件控制块
事件控制块使用的几点须知:
(1)任务或者中断服务子程序可以给事件控住块ECB发送信号。
(2)中断服务子程序不能等待事件控制块ECB给它发送信号的。
(3)等待事件可以设置超时时间,后面会详细的说明实现的原理。
(4)多个任务可以同时等待同一个事件发生,在这种情况下面,当事件发生后,所有等待该事件的任务中,只有优先级最高的任务得到该事件并进入就绪状态。
2、事件控制块的结构
(1)只有当所定义的事件是消息邮箱或者消息队列的时候才能使用,当所定义的事件是邮箱时,它指向的是一个消息;而当所定义的事件是消息队列时,它指向一个数据结构。
(2)此事件控制块指向的任务,用到的是位图的数据结构,而不是使用链表来访问任务结构
typedef struct os_event {
INT8U OSEventType; /* 事件控制块的类型 */
void *OSEventPtr; /* 指向事件需要带有的信息 */
INT16U OSEventCnt; /* 信号量计数器*/
OS_PRIO OSEventGrp; /* 事件优先级组*/
OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* 等待任务列表*/
#if OS_EVENT_NAME_EN > 0u
INT8U *OSEventName;
#endif
} OS_EVENT;
3、当任务接收到等待事件,然后将任务从就绪列表中删除,然后插入到等待的事件表中
prevent->OSEventGrp |= OSMapTbl[prio >> 3];
prevent->OSEventTbl[prio >> 3] |= OSMapTbl[prio & 0x07];
4、空闲事件控制块链表
(1)事件控制块的总数由应用程序所需要的信号量、互斥型信号量、邮箱以及消息队列的总数决定。
也就是:#define OS_MAX_EVENTS 语句定义。
(2)所有的事件控制块ECB被链接成一个单向链表–空闲事件控制块,并对其进行初始化。每当建立一个信号量,互斥型信号量,就从该链表中取出空余事件控制块。
5、初始化一个事件控制块OS_EventWaitListInit()
所有的任务之间进行的通信都需要通过调用这个事件控制块进行调用函数OS_EventWaitListinit();
该函数初始化一个空的等待任务列表,这个函数传递一个指针变量给事件控制块。
void OS_EventWaitListInit (OS_EVENT *pevent)
{
INT8U i;
pevent->OSEventGrp = 0u; /* No task waiting on event */
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
pevent->OSEventTbl[i] = 0u;
}