链表和任务管理是freertos 的核心,先分析链表源码,freertos的链表是双向环形链表,定义与数据结构在list.h中,表项的初始化,插入与删除在list.c中。
数据结构
一、表项数据结构
c
struct xLIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
void * pvOwner;
struct xLIST * configLIST_VOLATILE pxContainer;
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;
c
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
这两个是校验数据
c
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
#else
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
#endif
不需要的情况下宏展开为空,需下的的情况下是据TickType_t长度变化16-32位的5a5a
c
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
configLIST_VOLATILE TickType_t xItemValue;
c
#define configLIST_VOLATILE volatile
#ifndef configLIST_VOLATILE
#define configLIST_VOLATILE
#endif
在调度任务时,插入表项的依据值,可以为优先级什么的
c
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
指向下一表项
c
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
指向前一表项
c
void * pvOwner;
指向该表项的指针
c
struct xLIST * configLIST_VOLATILE pxContainer;
指向拥有该表项的链表。
二、链表数据结构
c
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE
volatile UBaseType_t uxNumberOfItems;
ListItem_t * configLIST_VOLATILE pxIndex;
MiniListItem_t xListEnd;
listSECOND_LIST_INTEGRITY_CHECK_VALUE
} List_t;
分解
c
volatile UBaseType_t uxNumberOfItems;
typedef unsigned long UBaseType_t;
表项数目
c
ListItem_t * configLIST_VOLATILE pxIndex;
表项索引
c
MiniListItem_t xListEnd;
表尾,若定义configUSE_MINI_LIST_ITEM ,使用缩减表项数据结构,否则还是表项的数据结构,参考以下
c
#if ( configUSE_MINI_LIST_ITEM == 1 )
struct xMINI_LIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;
#else
typedef struct xLIST_ITEM MiniListItem_t;
#endif