Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72731
  • 博文数量: 14
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 165
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-06 23:59
文章分类

全部博文(14)

文章存档

2009年(14)

我的朋友

分类:

2009-05-19 10:11:34

本次学习版本为5.2.0

*******************File:list.h & list.c*************************
1、几个重要的数据结构
struct xLIST_ITEM
{
     portTickType xItemValue; /*< The value being listed.  In most cases this is used to sort the list in descending order. */
     volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
     volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
     void * pvOwner; /*< 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 * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
};
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */

xItemValue
* pxNext
* pxPrevious
* pvOwner
* pvContainer
xListItem的结构

struct xMINI_LIST_ITEM
{
     portTickType xItemValue;
     volatile struct xLIST_ITEM *pxNext;
     volatile struct xLIST_ITEM *pxPrevious;
};
typedef struct xMINI_LIST_ITEM xMiniListItem;


typedef struct xLIST
{
     volatile unsigned portBASE_TYPE uxNumberOfItems;
     volatile xListItem * pxIndex; /*< Used to walk through the list.  Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
     volatile xMiniListItem xListEnd; /*< 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. */
} xList;

uxNumberOfItems
* pxIndex
xListEnd
xList的结构

xList是一个双向量表。xListEnd 只是作为一个标志,标志你此刻访问的是链表的尾部。它不存放有效的数据。它的next节点指向xList的头节点。

一个疑问:pxList->xListEnd.xItemValue到底做什么用?

2. 几个宏定义实现了对链表上节点的各种操作:
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )

3.定义了几个链表操作函数:
void vListInitialise( xList *pxList );
void vListInitialiseItem( xListItem *pxItem );
void vListInsert( xList *pxList, xListItem *pxNewListItem );        按照xListItem上的xItemValue值排序,然后插入。保证xItemValue是递增的。
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );   直接插到pxList->index的后面。
void vListRemove( xListItem *pxItemToRemove );



*******************File:task.h & task.c*************************

1、任务控制块结构
typedef struct tskTaskControlBlock
{
     volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
     xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */
     xListItem xEventListItem; /*< List item used to place the TCB in event lists. */
     unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */
     portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */
     signed portCHAR pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */

#if ( portSTACK_GROWTH > 0 )
     portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */
#endif

#if ( portCRITICAL_NESTING_IN_TCB == 1 )
     unsigned portBASE_TYPE uxCriticalNesting;
#endif

#if ( configUSE_TRACE_FACILITY == 1 )
     unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */
#endif
#if ( configUSE_MUTEXES == 1 )
     unsigned portBASE_TYPE uxBasePriority;
#endif

#if ( configUSE_APPLICATION_TASK_TAG == 1 )
     pdTASK_HOOK_CODE pxTaskTag;
#endif
} tskTCB;

*pxTopOfStack
xGenericListItem
xEventListItem
uxPriority
*pxStack
pcTaskName
*pxEndOfStack
uxCriticalNesting
uxTCBNumber
uxBasePriority
pxTaskTag
任务控制块的结构

2、各个API函数。
/*-----------------------------------------------------------
 * TASK CREATION API
 *----------------------------------------------------------*/
portBASE_TYPE xTaskCreate(
                              pdTASK_CODE pvTaskCode,
                              const portCHAR * const pcName,
                              unsigned portSHORT usStackDepth,
                              void *pvParameters,
                              unsigned portBASE_TYPE uxPriority,
                              xTaskHandle *pvCreatedTask
                          );
 void vTaskCode( void * pvParameters )
 {
     for( ;; )
     {
         // Task code goes here.
     }
 }

 // Function that creates a task.
 void vOtherFunction( void )
 {
 static unsigned char ucParameterToPass;
 xTaskHandle xHandle;
     // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
     // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
     // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
     // the new time attempts to access it.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
     // Use the handle to delete the task.
     vTaskDelete( xHandle );
 }


3、对于为什么要用到两个delaylist,我一直很不解。在vTaskIncrementTick()函数中:

if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
{
++xTickCount;
if( xTickCount == ( portTickType ) 0 )
{
xList *pxTemp;

/* Tick count has overflowed so we need to swap the delay lists.       XXXXXXXXXXXXXXXXXXXXXXXXXXXX
If there are any items in pxDelayedTaskList here then there is
an error! */
pxTemp = pxDelayedTaskList;
pxDelayedTaskList = pxOverflowDelayedTaskList;
pxOverflowDelayedTaskList = pxTemp;
            xNumOfOverflows++;
}

/* See if this tick has made a timeout expire. */
prvCheckDelayedTasks();
}
明白是为什么了!因为FreeRTOS系统的时钟管理原理是,每发生一个始终节拍,xTimeCount加1.这样有一种可能是,xTimeCount会溢出。所以在挂起一个任务的时候,计算xTimeToWake值与xTimeCount的关系。如果大,则是计数器正常,任务进入pxDelayedTaskList里面。而如果小了,说明xTimeCount溢出了。则该任务要进入到pxOverflowDelayedTaskList里面。这样,随着时间节拍数的增加致溢出时,挂起队列自然而然要进行切换。这也是为什么学要两个delayedList的原因啦!

*******************File:queue.h & queue.c*************************
1、queue的结构定义。
typedef struct QueueDefinition
{
signed portCHAR *pcHead; /*< Points to the beginning of the queue storage area. */
signed portCHAR *pcTail; /*< Points to the byte at the end of the queue storage area.  Once more byte is allocated than necessary to store the queue items, this is used as a marker. */

signed portCHAR *pcWriteTo; /*< Points to the free next place in the storage area. */
signed portCHAR *pcReadFrom; /*< Points to the last place that a queued item was read from. */

xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */

volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */

signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */
signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */

} xQUEUE;



*******************File:heap_2.c*************************
1、两个重要的数据结构
static struct xRTOS_HEAP
{
     unsigned portLONG ulDummy;
     unsigned portCHAR ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;

typedef struct A_BLOCK_LINK
{
     struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
     size_t xBlockSize; /*<< The size of the free block. */
} xBlockLink;
 
接下来,就是移植咯!
阅读(2508) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~