FREERTOS系统之tskTCB结构及其应用

 
2009-5-11      
 
也看了一些代码,至此才发现如果不对这个 tskTCB 结构有一定的认识,接下来根本就
无法再走下去了。故在此深刻研究下这个结构,该结构的定义如下:【在 task.c 文件中】其他很多地方都直接 typedef void tskTCB
typedef struct tskTaskControlBlock
{
/*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
       volatile portSTACK_TYPE     *pxTopOfStack;    
 
       /*< List item used to place the TCB in ready and blocked queues. */
       xListItem                      xGenericListItem;  
/*< List item used to place the TCB in event lists. */
xListItem                      xEventListItem;            
 
/*< The priority of the task where 0 is the lowest priority. */
       unsigned portBASE_TYPE    uxPriority;                          
 
       /*< Points to the start of the stack. */
portSTACK_TYPE               *pxStack;                    
 
/*< Descriptive name given to the task when created.  Facilitates debugging only. */
       signed portCHAR                 pcTaskName[ configMAX_TASK_NAME_LEN ];
 
       #if ( portSTACK_GROWTH > 0 )
/*< Used for stack overflow checking on architectures where the stack grows up from low memory. */
              portSTACK_TYPE *pxEndOfStack;                  
       #endif
 
       #if ( portCRITICAL_NESTING_IN_TCB == 1 )
              unsigned portBASE_TYPE uxCriticalNesting;
       #endif
 
       #if ( configUSE_TRACE_FACILITY == 1 )
              /*< This is used for tracing the scheduler and making debugging easier only. */
              unsigned portBASE_TYPE    uxTCBNumber;            
       #endif    
             
       #if ( configUSE_MUTEXES == 1 )
              unsigned portBASE_TYPE uxBasePriority;
       #endif
 
       #if ( configUSE_APPLICATION_TASK_TAG == 1 )
              pdTASK_HOOK_CODE pxTaskTag;
       #endif
             
} tskTCB;
一个 task 在创建完 TCP 和初始化栈之后,一般情况下就会被放入 readytask 链表中。上面的结构对我来说,比较难理解的应该是两个 xListItem 元素的变量了,不管如何,先看下这个结构的实现吧:
* Definition of the only type of object that a list can contain.
struct xLIST_ITEM
{
       /*< The value being listed.  In most cases this is used to sort the list in descending order. */
       portTickType xItemValue;                         
 
       /*< Pointer to the next xListItem in the list. */
       volatile struct xLIST_ITEM * pxNext; 
 
       /*< Pointer to the previous xListItem in the list. */
       volatile struct xLIST_ITEM * pxPrevious;
 
/*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
       void * pvOwner;                                             
 
       /*< Pointer to the list in which this list item is placed (if any). */
       void * pvContainer;                                         
};
 
/* For some reason lint wants this as two separate definitions. */
typedef struct xLIST_ITEM xListItem;             
嗯,到这里还算明白了一些,上面的两个 xListItem 变量是用来在某个什么时候作为一个 item 填充队列或链表。好了,问题来了,那具体是在什么时候,什么地方被加入的呢?
 
       还记得 prvInitialiseTaskLists ,前面提到过,但是没有深入讲解。这里就分析一下。
(1)       针对所有优先级,每个优先级创建一个链表,这个链表中存放的是该优先级已 ready task
(2)       一个 xDelayedTaskList1 链表
(3)       一个 xDelayedTaskList2 链表,主要是为了防止前面一个链表中 item 不够用的情况
(4)       一个 xPendingReadyList 链表
(5)       两个可选的链表: xTasksWaitingTermination xSuspendedTaskList
从名字上可以看出这些链表的作用所在。那接下来就有必要说下 xList 这个结构体,其定义如下:
* Definition of the type of queue used by the scheduler.
typedef struct xLIST
{
       volatile unsigned portBASE_TYPE uxNumberOfItems;
 
/*< Used to walk through the list.  Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
       volatile xListItem * pxIndex;               
 
/*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
       volatile xMiniListItem xListEnd;          
} xList;
这里说明一下,通过对各个使用 xList 的函数分析,该结构中的 xListEnd 是个环形链表。
struct xMINI_LIST_ITEM
{
       portTickType xItemValue;
       volatile struct xLIST_ITEM *pxNext;
       volatile struct xLIST_ITEM *pxPrevious;
};
这样就可以理解 xList 结构中的 pxIndex 的使用了,具体可参考 vListInsertEnd 的实现。同时 vListInitialise 函数的实现就可想而知了,以及 vListInsert vListRemove 都一块解决掉了。
 
嗯,是的,至此 freertos 中的三个重要的文件: queue.c list.c task.c ,我们已经解决了一个了。

你可能感兴趣的:(职场,休闲,freertos)