ucos-II 事件控制块源码分析

ucos-II 采用了事件控制块(ECB)的机制完成任务与任务、中断与任务之间的交互。并在此基础上扩展实现了信号量、互斥信号量、消息邮箱和消息队列。理解ucos-II的ECB主要看以下几方面的代码(包含在core.c中):

1. EVENT的定义:

typedef struct {
    INT8U   OSEventType; //事件控制块类型(见OS_EVENT_TYPE)
    INT8U   OSEventGrp;   //事件群体响应去等待任务事件发生
    INT16U  OSEventCnt;  //信号量,在其它事件中不用
    void   *OSEventPtr;     //消息或者队列结构指针
    INT8U   OSEventTbl[OS_EVENT_TBL_SIZE]; //任务列表等待事件发生
} OS_EVENT;

其中OSEventType中包括:

#define  OS_EVENT_TYPE_UNUSED          0
#define  OS_EVENT_TYPE_MBOX            1
#define  OS_EVENT_TYPE_Q               2
#define  OS_EVENT_TYPE_SEM             3
#define  OS_EVENT_TYPE_MUTEX           4
#define  OS_EVENT_TYPE_FLAG            5                

结构体中成员OSEventGrp和OSEventTbl,其结构体和使用机制与任务调度中是一样的

2.ECB的全局变量

ECB在初始阶段初始化两个全局变量,以维护一个EVENT资源的队列。

 

OS_EXT  OS_EVENT *OSEventFreeList; /* Pointer to list of free EVENT control blocks  */
OS_EXT  OS_EVENT OSEventTbl[OS_MAX_EVENTS];/* Table of EVENT control blocks */

 

3.ECB的核心函数

  1. 首先调用OSEventFreeList获取一个Event资源,然后通过OS_EventWaitListInit初始化,主要是初始化Event变量中的OSEventGrp和OSEventTbl两个成员变量;
  2. 当外部的XXPend函数被调用时(此时调用XXPend的任务已将自己的状态设置为XX_PEND等待挂起),此时调用OS_EventTaskWait,该准备被挂起的任务通过更新OSEventGrp和OSEventTbl两个成员变量记录下来;
  3. 当外部的XXPost函数被调用后,执行OS_EventTaskRdy。

      例如:OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM),此时pevent中的最高优先级任务被选择出来,通过置反取与完成状态清回OS_STAT_RDY,因为OS_STAT_RDY的值是0x00。然后该任务会被更新至全局就绪表等待被选择调度。

    ptcb->OSTCBStat     &= ~msk;   //事件状态位清除
    if (ptcb->OSTCBStat == OS_STAT_RDY) {  //如果任务就绪,(不能被挂起)
        OSRdyGrp        |=  bity;  /* Put task in the ready to run list */
        OSRdyTbl[y]     |=  bitx;
    }

 

 

posted @ 2013-01-24 10:49  Fredric_2013  阅读(2491)  评论(0编辑  收藏  举报