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;

    }

 

 

你可能感兴趣的:(源码分析)