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;
看图比较直观:
/* 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数据结构之间的联系可见下图:
四、内存控制块(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初始化的时候,都会建立这几个数据结构的缓冲区,每个缓冲区都是以单链表指针链接而成,以空指针 结束。系统运行时要使用到的控制块都是从这个缓冲区中获得,不使用的时候释放回缓冲区,因此,如果缓冲区中的控制块使用完了,就不能再分配控制块,这些都 在内核中有相应的控制,而初始化时,缓冲区的大小是通过在配置文件中进行设置来控制的。
初始化一共五个空闲缓冲区:任务控制块、事件控制块、消息队列控制块、标志控制块和存储控制块。如下图: