jzhang123 发表于 2013-12-11 16:04:48

ucos 事件控制块及处理函数(转)

ucos 事件控制块 及 处理函数

一.时间控制块ECB的数据结构
typedef struct {
    INT8U   OSEventType;                   /* Type of event control block (see OS_EVENT_TYPE_???)      */
    INT8U   OSEventGrp;                     /* Group corresponding to tasks waiting for event to occur*/
    INT16UOSEventCnt;                  /* Semaphore Count (not used if other EVENT type)         */
    void   *OSEventPtr;                     /* Pointer to message or queue structure                  */
    INT8U   OSEventTbl; /* List of tasks waiting for event to occur               */
} OS_EVENT;
.OSEventType      ECB类型有以下几种:
#defineOS_EVENT_TYPE_UNUSED      0
#defineOS_EVENT_TYPE_MBOX         1
#defineOS_EVENT_TYPE_Q               2
#defineOS_EVENT_TYPE_SEM         3
#defineOS_EVENT_TYPE_MUTEX       4
#defineOS_EVENT_TYPE_FLAG          5

.OSEventCnt   信号量计数表示最大空共享的数目

.*OSEventPtr用于消息和队列

.OSEventTbl[] 和 .OSEventGrp
分别与管理任务的OSRdyTbl[] 和 OSRdyGrp 类似,OSEventTbl[]用于放置该事件的所有等待任务。原理图如下:

http://hiphotos.baidu.com/ch314156/pic/item/0db9145411f63b3e84352473.jpg
二、将任务置于等待事件的任务列表
pevent->OSEventGrp |= OSMapTbl;
pevent->OSEventTbl |= OSMapTbl;
http://hiphotos.baidu.com/ch314156/pic/item/bc7bde392da0b7b23c6d977e.jpg
三、从等待任务列表中删除一个任务
if ((pevent->OSEventTbl &= ~OSMapTbl) == 0) {
pevent->OSEventGrp &= ~OSMapTbl;
}

四、在等待任务列表中查找最高优先级的任务
y = OSUnMapTbl;
x = OSUnMapTbl];
prio = (y << 3) + x;

五、空余事件控制块链表
在调用OSInit()时,所有事件控制块被链接成一个单向链表——空闲事件控制块链表。每当建立一个信号量、邮箱或者消息队列时,就从该链表中取出一个空闲事件控制块,并对它进行初始化。删除时,可将事件控制块放回到空余事件控制块链表中。
http://hiphotos.baidu.com/ch314156/pic/item/6086bafe5af095d59f514644.jpg

六、初始化一个事件控制块,OS_EventWaitListInit()
就是将该ECB中的.OSEventTbl[] 和 .OSEventGrp 全部清0


七、使一个任务进入就绪态,OS_EventTaskRdy()
先从等待任务列表中删除这个任务:
    if ((pevent->OSEventTbl &= ~bitx) == 0x00) {   /* Remove this task from the waiting list      */
      pevent->OSEventGrp &= ~bity;                  /* Clr group bit if this was only task pending   */
    }

http://hiphotos.baidu.com/ch314156/pic/item/6e35c5e9c74d6588b21cb146.jpg
再将这个任务置于任务就绪表:
    if (ptcb->OSTCBStat == OS_STAT_RDY) {             /* See if task is ready (could be susp'd)      */
      OSRdyGrp      |=bity;                     /* Put task in the ready to run list             */
      OSRdyTbl   |=bitx;
    }


八、使一个任务进入等待某事件发生状态,OS_EventTaskWait()

将任务移出就绪表
   
if ((OSRdyTbl &= ~OSTCBCur->OSTCBBitX) == 0x00) {   /* Task no longer ready      */
      OSRdyGrp &= ~OSTCBCur->OSTCBBitY;      /* Clear event grp bit if this was only task pending*/
    }

将任务进入该事件的等待列表
pevent->OSEventTbl |= OSTCBCur->OSTCBBitX;          /* Put task in waiting list*/
    pevent->OSEventGrp                   |= OSTCBCur->OSTCBBitY;


有了这些基本知识,后面的事件处理就简单多了

出处: http://hi.baidu.com/ch314156/item/e5de5438cb8da3677c034b13

jzhang123 发表于 2013-12-11 16:05:21

沙发               

jzhang123 发表于 2013-12-12 21:59:42

图片

本帖最后由 jzhang123 于 2013-12-12 22:09 编辑

                        
。。。            
页: [1]
查看完整版本: ucos 事件控制块及处理函数(转)