uc/os-ii事件控制块
2015-07-02 16:21
176 查看
任务间的同步依赖于任务间的通信。在μC/OS-II中,使用信号量、互斥信号量、消息邮箱、消息队列、事件标志组这些被称作事件的中间环节来实现任务之间的通信的。为了把描述事件的数据结构统一起来,μC/OS-II使用叫做事件控制块ECB的数据结构来描述诸如信号量、互斥信号量、消息邮箱、消息队列、事件标志组这些事件。
事件控制块中包含包括等待任务表在内的所有有关事件的数据 。
图示为事件控制块的内存结构图。
![](http://img.blog.csdn.net/20150702161747334)
一般地,对于事件控制块进行如下一些通用操作:
OS_EventWaitListInit():初始化事件控制块。
初始化等待任务列表为全0,没有任务在等待事件。
OS_EventTaskRdy():使任务进入就绪态。
当某个事件发生后,就要使等待任务列表中优先级最高的任务脱离等待,并置于就绪状态。
OS_EventTaskWait():使任务进入等待某事件发生状态
当某个任务要等待一个事件发生时,相应OSSemPend()、OSMutexPend()、OSMboxPend()或OSQPend()函数会调用OSEventTaskWait()函数将当前任务从任务就绪表中删除,并放到相应事件的事件控制块的等待任务列表中。
OS_EventTaskRemove() : 删除任务对某时间的等待状态
事件控制块中包含包括等待任务表在内的所有有关事件的数据 。
#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;
图示为事件控制块的内存结构图。
一般地,对于事件控制块进行如下一些通用操作:
OS_EventWaitListInit():初始化事件控制块。
初始化等待任务列表为全0,没有任务在等待事件。
void OS_EventWaitListInit (OS_EVENT *pevent) { #if OS_LOWEST_PRIO <= 63 INT8U *ptbl; #else INT16U *ptbl; #endif INT8U i; pevent->OSEventGrp = 0; /* No task waiting on event */ ptbl = &pevent->OSEventTbl[0]; for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { *ptbl++ = 0; } }
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 > 63 INT16U *ptbl; #endif #if OS_LOWEST_PRIO <= 63 y = OSUnMapTbl[pevent->OSEventGrp]; /* Find HPT waiting for message */ x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (INT8U)((y << 3) + x); /* Find priority of task getting the msg */ #else if ((pevent->OSEventGrp & 0xFF) != 0) { /* Find HPT waiting for message */ y = OSUnMapTbl[ pevent->OSEventGrp & 0xFF]; } else { y = OSUnMapTbl[(pevent->OSEventGrp >> 8) & 0xFF] + 8; } ptbl = &pevent->OSEventTbl[y]; if ((*ptbl & 0xFF) != 0) { x = OSUnMapTbl[*ptbl & 0xFF]; } else { x = OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8; } prio = (INT8U)((y << 4) + x); /* Find priority of task getting the msg */ #endif ptcb = OSTCBPrioTbl[prio]; /* Point to this task's OS_TCB */ ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from readying task */ #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) ptcb->OSTCBMsg = pmsg; /* Send message directly to waiting task */ #else pmsg = pmsg; /* Prevent compiler warning if not used */ #endif ptcb->OSTCBStat &= ~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 > 0) 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); }
OS_EventTaskWait():使任务进入等待某事件发生状态
当某个任务要等待一个事件发生时,相应OSSemPend()、OSMutexPend()、OSMboxPend()或OSQPend()函数会调用OSEventTaskWait()函数将当前任务从任务就绪表中删除,并放到相应事件的事件控制块的等待任务列表中。
void OS_EventTaskWait (OS_EVENT *pevent) { INT8U y; OSTCBCur->OSTCBEventPtr = pevent; /* Store ptr to ECB in TCB */ pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Put task in waiting list */ pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; y = OSTCBCur->OSTCBY; /* Task no longer ready */ OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; if (OSRdyTbl[y] == 0) { OSRdyGrp &= ~OSTCBCur->OSTCBBitY; /* Clear event grp bit if this was only task pending */ } }
OS_EventTaskRemove() : 删除任务对某时间的等待状态
void OS_EventTaskRemove (OS_TCB *ptcb, OS_EVENT *pevent) { INT8U y; y = ptcb->OSTCBY; pevent->OSEventTbl[y] &= ~ptcb->OSTCBBitX; /* Remove task from wait list */ if (pevent->OSEventTbl[y] == 0) { pevent->OSEventGrp &= ~ptcb->OSTCBBitY; } }
相关文章推荐
- 阿里巴巴常考面试题及汇总答案
- Android动画之LayoutAnimationController
- Linux服务器上监控网络带宽的18个常用命令
- Linux服务器上监控网络带宽的18个常用命令
- iOS集成支付宝问题
- 都说了是随笔了还要什么标题
- linux ./configure 的参数详解
- sso笔记
- 60. C# -- 读取 appconfig文件配置数据库连接的方法
- 修改 editButtonItem.title
- WinXP无法删除视频文件如果不是因为权限该如何处理
- 三分钟教你学Git(十七) - 钩子
- Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用
- Qt入门之utf8与unicode转换
- VS2010调用tesseract步骤
- linux shell学习笔记mkdir
- Android 虚拟按键驱动实现
- HNOI2008玩具装箱toy题解
- Netty权威指南之私有协议栈开发
- 变化的心脏形图片