原创 FreeRTOS学习笔记

2009-5-19 10:15 3275 5 6 分类: MCU/ 嵌入式

本次学习版本为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;

 

接下来就是移植了。嘿嘿
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

michael_xing 2010-3-25 11:33

谢谢,讲得非常好。
相关推荐阅读
用户140288 2009-06-22 21:18
汉字点阵字库的原理与显示
一、什么是点阵?我们先看两个字的点阵图:A字母的点阵是这样的:8×16汉字“你”的点阵是这样的:16×16以上的两个文字的字模信息,应该让我们很清楚的明白了文字的显示原理。但是又是如何获取这些字模信息...
用户140288 2009-06-10 00:07
openSUSE LiveCD 11.1 的硬盘安装
前阵子无意间接触了openSUSE linux感觉这个发行版还是蛮清爽的。有点想试试的冲动,下了个liveCD11.1,刻了盘,要安装的时候,结果发现我的CDROM弹不出来。最后没辙了,只好改硬盘的安...
用户140288 2009-06-07 15:20
中点画线算法-原理及实现
计算机图形学-中点画线算法 在编写的FDGK/GUI决定采用中点画线算法绘制直线。故先研究了一下算法。中点画线算法的原则是:如下图所示,但斜率K<1时,选定一个点之后,再计算中点M。如果M>...
用户140288 2009-06-02 17:12
UML学习笔记
20090526 UML概述UML:unified modeling language。统一建模语言模型就是对现实的简化。认识误区:UML是一种方法论:UML是一种语言UML是一堆图形:图形只是建模的...
用户140288 2009-05-22 15:58
LCD drive 学习笔记
see also: http://docs.google.com/View?id=dhd5grmt_366g7bns5c2LCD原理及驱动最近有在用SmartARM2200的开发板,上面有带一块tft...
用户140288 2009-05-19 10:18
FreeRTOS移植笔记
本次移植的目标板是:easyARM2104. 用ADS1.2作为调试平台。移植前,看了一下官方的一些参考治疗,我摘抄了一些:1、configuration the Time tick interrup...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条