ucos-II学习之:数据结构(任务控制块/事件控制块/内存控制块总结一)

http://liangruyi1986.blog.163.com/blog/static/17756123201431513050819/

无论是应用程序还是内核程序,其实都是对某些数据结构的增删改查之类的操作,所以,一个系统设计的好坏,始于数据结构的定义,要弄清楚一个系统,也应该从其最底层的数据结构着手。

      ucos-II涉及到的最核心的数据结构并不多,只有几个结构体,整个内核中的任务调试、任务同步、任务通信以及内存管理都是对这几个数据结构的操作。

     一、任务控制块(Task Control Blocks,OS_TCB),这是一个用来保存任务各种状态信息的数据结构。代码copy过来:
typedef struct os_tcb {
    OS_STK        *OSTCBStkPtr;     /* Pointer to current top of stack       */
#if OS_TASK_CREATE_EXT_EN > 0      
    void          *OSTCBExtPtr;        /* Pointer to user definable data for TCB extension  */
    OS_STK        *OSTCBStkBottom;     /* Pointer to bottom of stack   */
    INT32U         OSTCBStkSize;       /* Size of task stack (in number of stack elements)   */
    INT16U         OSTCBOpt;           /* Task options as passed by OSTaskCreateExt()   */
    INT16U         OSTCBId;            /* Task ID (0..65535)        */
#endif
    struct os_tcb *OSTCBNext;          /* Pointer to next     TCB in the TCB list    */
    struct os_tcb *OSTCBPrev;          /* Pointer to previous TCB in the TCB list    */
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)
    OS_EVENT      *OSTCBEventPtr;      /* Pointer to event control block   */
#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_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
#if OS_TASK_DEL_EN > 0         
    OS_FLAG_NODE  *OSTCBFlagNode;      /* Pointer to event flag node   */
#endif    
    OS_FLAGS       OSTCBFlagsRdy;      /* Event flags that made task ready to run  */
#endif
    INT16U         OSTCBDly;           /* Nbr ticks to delay task or, timeout waiting for event */
    INT8U          OSTCBStat;          /* Task status      */
    INT8U          OSTCBPrio;          /* Task priority (0 == highest, 63 == lowest) */
    INT8U          OSTCBX;             /* Bit position in group  corresponding to task priority (0..7) */
    INT8U          OSTCBY;             /* Index into ready table corresponding to task priority        */
    INT8U          OSTCBBitX;          /* Bit mask to access bit position in ready table  */
    INT8U          OSTCBBitY;          /* Bit mask to access bit position in ready group    */
#if OS_TASK_DEL_EN > 0
    BOOLEAN        OSTCBDelReq;        /* Indicates whether a task needs to delete itself    */
#endif
} OS_TCB;
 
      二、事件控制块(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  */
    INT16U  OSEventCnt;   /* Semaphore Count (not used if other EVENT type)  */
    void   *OSEventPtr;       /* Pointer to message or queue structure         */
    INT8U   OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur       */
} OS_EVENT;
看图比较直观:

ucos-II学习之:数据结构(任务控制块/事件控制块/内存控制块总结一) - lry - 我的博客

/* Pointer to where next message will be inserted  in   the Q  */
    void         **OSQOut;        /* Pointer to where next message will be extracted from the Q  */
    INT16U         OSQSize;        /* Size of queue (maximum number of entries)   */
    INT16U         OSQEntries;     /* Current number of entries in the queue     */
} OS_Q;OS_Q实现为一个循环的环形队列。下图所示的就是当事件定义为消息队列时,总个数据结构的构成,


三、事件标志组,主要是用于任务间的通信。事件标志组中涉及到的数据结构有OS_FLAG_GRP(事件标志组)和OS_FLAG_NODE(事件标志结点)。      

OS_FLAG_GRP的代码如下:
typedef struct {                            /* Event Flag Group           */
    INT8U         OSFlagType;           /* Should be set to OS_EVENT_TYPE_FLAG    */
    void         *OSFlagWaitList;      /* Pointer to first NODE of task waiting on event flag     */
    OS_FLAGS      OSFlagFlags;       /* 8, 16 or 32 bit flags           */
} OS_FLAG_GRP;    
其中OSFlagWaitList指向事件标志组的等待任务列表,这个列表其实是由OS_FLAG_NODE结构组成的一个双向链表。
OS_FLAG_NODE的代码如下:
typedef struct {                            /* Event Flag Wait List Node          */
    void         *OSFlagNodeNext;           /* Pointer to next     NODE in wait list      */
    void         *OSFlagNodePrev;           /* Pointer to previous NODE in wait list     */
    void         *OSFlagNodeTCB;            /* Pointer to TCB of waiting task     */  
    void         *OSFlagNodeFlagGrp;        /* Pointer to Event Flag Group     */  
    OS_FLAGS      OSFlagNodeFlags;          /* Event flag to wait on     */  
    INT8U         OSFlagNodeWaitType;       /* Type of wait:   */
                                            /*      OS_FLAG_WAIT_AND       */
                                            /*      OS_FLAG_WAIT_ALL     */
                                            /*      OS_FLAG_WAIT_OR      */
                                            /*      OS_FLAG_WAIT_ANY     */
} OS_FLAG_NODE;
事件标志组两数据结构之间的联系以及和OS_TCB数据结构之间的联系可见下图:

ucos-II学习之:数据结构(任务控制块/事件控制块/内存控制块总结一) - lry - 我的博客

四、内存控制块(MCB),实现内存管理、跟踪每一个内存分区的数据结构,代码:

typedef struct {                       /* MEMORY CONTROL BLOCK        */
    void   *OSMemAddr;           /* Pointer to beginning of memory partition     */
    void   *OSMemFreeList;         /* Pointer to list of free memory blocks          */
    INT32U  OSMemBlkSize;      /* Size (in bytes) of each block of memory   */
    INT32U  OSMemNBlks;        /* Total number of blocks in this partition        */
    INT32U  OSMemNFree;        /* Number of memory blocks remaining in this partition   */
} OS_MEM;
见图:

ucos-II学习之:数据结构(任务控制块/事件控制块/内存控制块总结一) - lry - 我的博客

这些即是核心的几个数据结构,在ucos-II初始化的时候,都会建立这几个数据结构的缓冲区,每个缓冲区都是以单链表指针链接而成,以空指针 结束。系统运行时要使用到的控制块都是从这个缓冲区中获得,不使用的时候释放回缓冲区,因此,如果缓冲区中的控制块使用完了,就不能再分配控制块,这些都 在内核中有相应的控制,而初始化时,缓冲区的大小是通过在配置文件中进行设置来控制的。

      初始化一共五个空闲缓冲区:任务控制块、事件控制块、消息队列控制块、标志控制块和存储控制块。如下图:
ucos-II学习之:数据结构(任务控制块/事件控制块/内存控制块总结一) - lry - 我的博客
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值