文章目录
0 前言
@ Author :Dargon
@ Record Date :2021/07/12
@ Reference Book : `FreeRTOS源码详解与应用开发`,`ARM Cortex-M3与Cortex-M4权威指南`,`B站正点原子FreeRTOS讲解视频`
@ Purpose :学习正点原子的miniFly,该飞控基于FreeRTOS系统开发的,所以学习一下记录下关于RTOS系统的一些基本操作,大概了解系统的工作原理,如何创建,运行,切换任务等等基本操作流程。在此进行学习的记录。
1 列表基础知识
1.1 列表List_t
- List_t 结构体定义
typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE UBaseType_t uxNumberOfItems; ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ MiniListItem_t 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. */ listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ } List_t;
uxNumberOfItems
表示列表中列表项的个数pxIndex
用来遍历列表,一个列表项ListItem_t类型的指针xListEnd
用作一个标记,位于列表的末尾
1.2 列表项ListItem_t
- ListItem_t 结构体定义
struct xLIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t 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 * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ }; typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
xItemValue
表示该列表项的值pxNext
指向前一个列表项pxPrevious
指向后一个列表项pvOwner
指向所属于哪个任务块,对应于TBC_t 中的 xStateListItem->pvOwnerpvContainer
指向当前所属于的列表
1.3 Mini列表项MiniListItem_t
- MiniListItem_t 结构体定义
由于只用作列表的最后一项,只是做个标记而已,减少内存的浪费,简化的省略一些成员变量。struct xMINI_LIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ configLIST_VOLATILE TickType_t xItemValue; struct xLIST_ITEM * configLIST_VOLATILE pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; }; typedef struct xMINI_LIST_ITEM MiniListItem_t;
xItemValue
表示该列表项的值pxNext
指向前一个列表项pxPrevious
指向后一个列表项
2 API函数的实现
2.1 列表初始化 vListInitialise()
- vListInitialise() 初始化源码分析
void vListInitialise( List_t * const pxList ) { /* The list structure contains a list item which is used to mark the end of the list. To initialise the list the list end is inserted as the only list entry. */ pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ /* The list end value is the highest possible value in the list to ensure it remains at the end of the list. */ pxList->xListEnd.xItemValue = portMAX_DELAY; /* The list end next and previous pointers point to itself so we know when the list is empty. */ pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->uxNumberOfItems = ( UBaseType_t ) 0U; /* Write known values into the list if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); }
- 将index 指向xListEnd
- 初始化
pxList->xListEnd.xItemValue = portMAX_DELAY;
为最大值,确保在列表的末端 - 初始化
pxList->xListEnd.pxNext
和pxList->xListEnd.pxPrevious
- 初始化
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
列表项个数为0
2.2 列表项初始化 vListInitialiseItem()
- vListInitialiseItem()
void vListInitialiseItem( ListItem_t * const pxItem ) { /* Make sure the list item is not recorded as being on a list. */ pxItem->pvContainer = NULL; /* Write known values into the list item if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); }
- pxItem->pvContainer = NULL; 仅仅初始化次列表项的列表属性为 null
2.3 列表插入 vListInsert()
- vListInsert()
- 获取要插入的列表项的值
- 遍历列表,找到位置
- 更新next 和 previous
- 更新该插入列表值的pxNewListItem->pvContainer
- 列表
( pxList->uxNumberOfItems )++;
需要更新
2.4 列表末尾插入 vListInsertEnd()
- vListInsertEnd()
pxNewListItem->pxNext = pxIndex; pxNewListItem->pxPrevious = pxIndex->pxPrevious; /* Only used during decision coverage testing. */ mtCOVERAGE_TEST_DELAY(); pxIndex->pxPrevious->pxNext = pxNewListItem; pxIndex->pxPrevious = pxNewListItem; /* Remember which list the item is in. */ pxNewListItem->pvContainer = ( void * ) pxList; ( pxList->uxNumberOfItems )++;
- 直接更新列表项的next 和previous即可
2.5 列表删除 uxListRemove()
- uxListRemove()
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) { /* The list item knows which list it is in. Obtain the list from the list item. */ List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; /* Only used during decision coverage testing. */ mtCOVERAGE_TEST_DELAY(); /* Make sure the index is left pointing to a valid item. */ if( pxList->pxIndex == pxItemToRemove ) { pxList->pxIndex = pxItemToRemove->pxPrevious; } else { mtCOVERAGE_TEST_MARKER(); } pxItemToRemove->pvContainer = NULL; ( pxList->uxNumberOfItems )--; return pxList->uxNumberOfItems; }
- 根据
pxItemToRemove->pvContainer
,获得所在的列表 - 进行更新next 和 previous
- 若是当前的index 指向的是被删除的,则进行更新到指向被删除的前一个列表项
- 更新列表项的个数( pxList->uxNumberOfItems )–;
- 根据