UCOSII三大控制块

前面总结了UCOSII下的任务调度以及任务间的同步与通信机制,这篇文章简单总结下UCOSII下的三大控制块:TCB(任务控制块)、ECB(事件控制块)以及MCB(内存控制块)

UCOSII初始化时建立的五大缓冲区(以单链表的形式存在):

若当使用相应控制块时则向缓冲区申请,不使用时释放回缓冲区,若缓冲区中的相应控制块使用完了,则不能再分配相应控制块。在初始化时可配置缓冲区大小

TCB(Task_Control_Block)任务控制块:

/*
*********************************************************************************************************
*                                          TASK CONTROL BLOCK
*********************************************************************************************************
*/

typedef struct os_tcb {
    OS_STK          *OSTCBStkPtr;           /* 当前任务的栈顶地址(UCOSII中每个任务都有自己的栈)且容量任意 */

#if OS_TASK_CREATE_EXT_EN > 0
    void            *OSTCBExtPtr;           /*只在OstaskCreateExt()函数中使用,用于用户扩展任务控制*/
    OS_STK          *OSTCBStkBottom;        /* 指向任务可以使用的栈空间的最高地址,一般在OSTaskStkChk()函数中使用 */
    INT32U           OSTCBStkSize;          /*存有栈中可容纳的指针数目,在OSTaskStkChk()函数中使用*/
    INT16U           OSTCBOpt;              /* 将选项传递给OstaskCreateExt()函数 */
    INT16U           OSTCBId;               /* Task ID (0..65535)用于存储任务识别码,暂无用,留作扩展 */
#endif

    struct os_tcb   *OSTCBNext;             /* TCB链表下一个任务对应的TCB块,在OSTimeTick()函数中被调用,用于刷新任务延迟变量OSTCBDly */
    struct os_tcb   *OSTCBPrev;             /* 与上面类似(每个任务在创建时都将被加入TCB链表中) */

#if (OS_EVENT_EN) || (OS_FLAG_EN > 0)
    OS_EVENT        *OSTCBEventPtr;         /* 指向事件控制块的指针 */
#endif

#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0)
    OS_EVENT       **OSTCBEventMultiPtr;    /* 指向多事件控制块的指针 */
#endif

#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
    void            *OSTCBMsg;              /* Message received from OSMboxPost() or OSQPost(),指向消息地址 */
#endif

#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
#if OS_TASK_DEL_EN > 0
    OS_FLAG_NODE    *OSTCBFlagNode;         /* 指向 事件标志节点 */
#endif
    OS_FLAGS         OSTCBFlagsRdy;         /* 使得任务准备运行(进入就绪态的事件标志)的标志 */
#endif

    INT16U           OSTCBDly;              /* 任务等待(挂起)时限,对应各种pend函数 */
    INT8U            OSTCBStat;             /* 任务状态,0:就绪,1:等待(挂起)信号量状态,2:等待(挂起)消息邮箱状态,3:等待(挂起)消息队列状态,4:Suspend(挂起)状态(此挂起只有Resume可解),5:等待(挂起)互斥信号量状态 */
    INT8U            OSTCBStatPend;         /* 等状态的状态标志,0:等待状态OK,非等待状态或等待完成状态,1:等待超时状态,2:等待中止状态 */
    INT8U            OSTCBPrio;             /* 储存任务优先级(0 == highest) */

    INT8U            OSTCBX;                /* 任务优先级计算参数,优先级低3位对应的数值,即prio & 0x07 */
    INT8U            OSTCBY;                /* 任务优先级高3位对应的值,即prio >> 3(存有疑问?) */
#if OS_LOWEST_PRIO <= 63
    INT8U            OSTCBBitX;             /* 对应就绪表组的值,OSRdyTbl[OSTCBY] |= OSTCBBitX */
    INT8U            OSTCBBitY;             /* 就绪表组OSRdyGrp |= OSTCBBitY 即上行所提到的对应组 */
#else
    INT16U           OSTCBBitX;             /* Bit mask to access bit position in ready table          */
    INT16U           OSTCBBitY;             /* Bit mask to access bit position in ready group          */
#endif

#if OS_TASK_DEL_EN > 0
    INT8U            OSTCBDelReq;           /* 标识该任务十分需要被删除 */
#endif

#if OS_TASK_PROFILE_EN > 0
    INT32U           OSTCBCtxSwCtr;         /* 表示任务被调用的次数 */
    INT32U           OSTCBCyclesTot;        /* 该任务运行的节拍总数 */
    INT32U           OSTCBCyclesStart;      /* 该任务恢复开始时的节拍数 */
    OS_STK          *OSTCBStkBase;          /* 该任务堆栈的开始位置 */
    INT32U           OSTCBStkUsed;          /* 该任务堆栈已被使用的字节数 */
#endif

#if OS_TASK_NAME_SIZE > 1
    INT8U            OSTCBTaskName[OS_TASK_NAME_SIZE];/* 该任务的名称 */
#endif
} OS_TCB;  

ECB(Event_Control_Block)事件控制块:

/*
*********************************************************************************************************
*                                          EVENT CONTROL BLOCK
*********************************************************************************************************
*/

#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0)
typedef struct os_event {
    INT8U    OSEventType;                    /*事件控制块的类型(OS_EVENT_TYPE_UNUSED(未使用)、OS_EVENT_TYPE_MBOX、OS_EVENT_TYPE_Q、OS_EVENT_TYPE_SEM、OS_EVENT_TYPE_MUTEX和OS_EVENT_TYPE_FLAG) */
    void    *OSEventPtr;                     /* 指向消息或消息队列中消息结构体的指针,只在邮箱和消息队列事件中存在 */
    INT16U   OSEventCnt;                     /* 当事件类型为信号量时的计数器 */
#if OS_LOWEST_PRIO <= 63
    INT8U    OSEventGrp;                     /* 等待某事件的任务表组 */
    INT8U    OSEventTbl[OS_EVENT_TBL_SIZE];  /* 等待某事件的任务表 */
#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;
#endif  

MCB(Memory_Control_Block)事件控制块:

/*
*********************************************************************************************************
*                                     MEMORY PARTITION DATA STRUCTURES
*********************************************************************************************************
*/

#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
typedef struct os_mem {                   /* MEMORY CONTROL BLOCK                                      */
    void   *OSMemAddr;                    /* 内存分区的首地址 */
    void   *OSMemFreeList;                /* 内存控制块组成的链表头地址 */
    INT32U  OSMemBlkSize;                 /* 每个内存控制块的大小(字节) */
    INT32U  OSMemNBlks;                   /* 内存分区中内存控制块的数目 */
    INT32U  OSMemNFree;                   /* 内存分区中空闲内存控制块的数目 */
#if OS_MEM_NAME_SIZE > 1
    INT8U   OSMemName[OS_MEM_NAME_SIZE];  /* 内存分区的名字 */
#endif
} OS_MEM;


typedef struct os_mem_data {
    void   *OSAddr;                    /* Pointer to the beginning address of the memory partition     */
    void   *OSFreeList;                /* Pointer to the beginning of the free list of memory blocks   */
    INT32U  OSBlkSize;                 /* Size (in bytes) of each memory block                         */
    INT32U  OSNBlks;                   /* Total number of blocks in the partition                      */
    INT32U  OSNFree;                   /* Number of memory blocks free                                 */
    INT32U  OSNUsed;                   /* Number of memory blocks used                                 */
} OS_MEM_DATA;
#endif