从零开始学习UCOSII操作系统6--事件控制块
2018-03-30 21:36
405 查看
从零开始学习UCOSII操作系统6--事件控制块
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; } }
6、使一个任务进入就绪态:OS_EventTaskRdy()
就是简单的对就绪表进行相应的赋值就行。就是接收到相应的事件的时候把任务放置到就绪态中。信号量、互斥型信号量、消息邮箱、消息队列所对应的POST函数调用OS_EventTaskRdy(),以实现该操作。该函数的主要的功能就是将等待队列中使最高优先级任务脱离等待任务,并把该任务置于就绪态中。
INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *pmsg, INT8U msk, INT8U pend_stat) { OS_TCB *ptcb; INT8U y; INT8U x; INT8U prio; #if OS_LOWEST_PRIO > 63u OS_PRIO *ptbl; #endif #if OS_LOWEST_PRIO <= 63u y = OSUnMapTbl[pevent->OSEventGrp]; /* Find HPT waiting for message */ x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (INT8U)((y << 3u) + x); /* Find priority of task getting the msg */ #else if ((pevent->OSEventGrp & 0xFFu) != 0u) { /* Find HPT waiting for message */ y = OSUnMapTbl[ pevent->OSEventGrp & 0xFFu]; } else { y = OSUnMapTbl[(OS_PRIO)(pevent->OSEventGrp >> 8u) & 0xFFu] + 8u; } ptbl = &pevent->OSEventTbl[y]; if ((*ptbl & 0xFFu) != 0u) { x = OSUnMapTbl[*ptbl & 0xFFu]; } else { x = OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u; } prio = (INT8U)((y << 4u) + x); /* Find priority of task getting the msg */ #endif ptcb = OSTCBPrioTbl[prio]; /* Point to this task's OS_TCB */ ptcb->OSTCBDly = 0u; /* Prevent OSTimeTick() from readying task */ #if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u) ptcb->OSTCBMsg = pmsg; /* Send message directly to waiting task */ #else pmsg = pmsg; /* Prevent compiler warning if not used */ #endif ptcb->OSTCBStat &= (INT8U)~msk; /* Clear bit associated with event type */ ptcb->OSTCBStatPend = pend_stat; /* Set pend status of post or abort */ /* See if task is ready (could be susp'd) */ if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { OSRdyGrp |= ptcb->OSTCBBitY; /* Put task in the ready to run list */ OSRdyTbl[y] |= ptcb->OSTCBBitX; } OS_EventTaskRemove(ptcb, pevent); /* Remove this task from event wait list */ #if (OS_EVENT_MULTI_EN > 0u) if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { /* Remove this task from events' wait lists */ OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr); ptcb->OSTCBEventPtr = (OS_EVENT *)pevent;/* Return event as first multi-pend event ready*/ } #endif return (prio); }相当于等待事件的发生:
也就是收到相应的事件就可以直接把任务从事件等待的列表中移除了。
void OS_EventTaskWait (OS_EVENT *pevent) { INT8U y; OSTCBCur->OSTCBEventPtr = pevent; /* Store ptr to ECB in TCB */ pevent->OSEv b49e entTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Put task in waiting list */ pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; y = OSTCBCur->OSTCBY; /* Task no longer ready */ OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX; if (OSRdyTbl[y] == 0u) { /* Clear event grp bit if this was only task pending */ OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY; } }
相关文章推荐
- 从零开始学习UCOSII操作系统9--事件标志组
- 从零开始学习UCOSII操作系统4--任务管理
- 从零开始学习UCOSII操作系统7--信号量
- 从零开始学习UCOSII操作系统12--内存管理
- 从零开始学习UCOSII操作系统5--时间管理
- 从零开始学习UCOSII操作系统2--UCOSII的内核实现
- 从零开始学习UCOSII操作系统1--UCOSII的基础知识
- 从零开始学习UCOSII操作系统10--消息邮箱
- 从零开始学习UCOSII操作系统3--UCOSII启动过程
- 从零开始学习在Windows2003操作系统下安装IIS组件
- 4、从零开始学习JAVA--流程控制
- 从零开始学习jQuery (五) jquery事件与事件对象
- JS学习1--基础、DOM控制Html元素、JS事件
- CocosCreator项目学习系列<二>关于Button(添加事件)输入控制交互条件的触发_实现虚拟按钮控制_JavaScript
- 从零开始学习VC++6.0之并口控制(第五课 步进电机启动)
- 从零开始学习jQuery (五) 事件与事件对象
- 从零开始学习jQuery (五) 事件与事件对象
- Node.js学习开始了——事件流的控制/文件读写事件的的方法
- 5.从零开始学习C语言--C语言运算符和流程控制
- 从零开始学习音视频编程技术(十) FFMPEG Qt视频播放器之播放控制