当前位置: 首页 > news >正文

FreeRTOS学习笔记【11】-----任务列表

根据b站up freeRTOS源码

数据结构

1 TCB(task control block)

typedef struct tskTaskControlBlock       /* The old naming convention is used to prevent breaking kernel aware debuggers. */
{volatile StackType_t * pxTopOfStack; /**< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. *///指向任务栈顶部的指针ListItem_t xStateListItem;                  /**< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). *///用于将任务链接到不同状态列表(就绪、阻塞、挂起)的列表项。ListItem_t xEventListItem;                  /**< Used to reference a task from an event list. *///用于将任务链接到事件列表的列表项。UBaseType_t uxPriority;                     /**< The priority of the task.  0 is the lowest priority. *///任务的优先级,数值越小优先级越低。StackType_t * pxStack;                      /**< Points to the start of the stack. *///指向任务栈起始地址的指针char pcTaskName[ configMAX_TASK_NAME_LEN ];
} tskTCB;

2 任务列表项

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 ascending 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. *///指向“拥有”该 list item 的对象。通常是一个任务控制块(TCB)。struct xLIST * configLIST_VOLATILE pxContainer;     /**< Pointer to the list in which this list item is placed (if any). *///指列表项所处的列表(就绪列表、delay列表、挂起列表)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;

3 列表头

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; /**< Number of items in the list. */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;

列表代码

1 列表初始化

freeRTOS的列表变量:

PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; 
/**< 用于存储就绪态(Ready)的任务列表. */
PRIVILEGED_DATA static List_t xDelayedTaskList1;                         
/**< 用于存储延迟(Delayed)的任务 */
PRIVILEGED_DATA static List_t xDelayedTaskList2;                         
/**< xDelayedTaskList2 用于存储那些延迟时间超过了当前 tick 计数范围的任务. */
PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;              
/**< 当前正在使用的延迟任务列表.延迟时间超过了当前 tick 计数器的范围时,这些任务会被放入  */
PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList;      
/**< 指向当前用于存储溢出延迟任务的列表. */
PRIVILEGED_DATA static List_t xPendingReadyList;                         
/**< 用于存储那些由于某些事件(如信号量释放、队列操作等)而变为就绪态的任务 */

2 列表初始化

pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );pxList->xListEnd.xItemValue = portMAX_DELAY;
//0xffffffffU 
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );pxList->uxNumberOfItems = ( UBaseType_t ) 0U;

3 Insert 函数

void vListInsert( List_t * const pxList,ListItem_t * const pxNewListItem )

pxList 要插入的列表,
pxNewListItem 要插入的列表项

	ListItem_t * pxIterator;//将新列表项插入在pxIterator指向位置的后面pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;

那么,pxIterator的是如何定位的呢?

	//如果value最大,就放在尾结点的前面if( xValueOfInsertion == portMAX_DELAY ){pxIterator = pxList->xListEnd.pxPrevious;}else{//初始化,迭代器指向尾部//停止条件,迭代器的下一个节点的值小于等于当前值//否则 迭代器指向下一个节点for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ){/* There is nothing to do here, just iterating to the wanted* insertion position. */}

4 InsertEnd函数

这里的End是对于遍历而言的End,
listGET_OWNER_OF_NEXT_ENTRY中,需要对list进行遍历

    do {                                                                                       \List_t * const pxConstList = ( pxList );                                               \/* Increment the index to the next item and return the item, ensuring */               \/* we don't return the marker used at the end of the list.  */                         \( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                           \if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \{                                                                                      \( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext;                       \}                                                                                      \( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                         \} while( 0 )

InsertEnd 函数存在的含义是:

并不是把当前要插入的项插到列表尾
而是要把列表放在遍历时最后一个遍历的位置

http://www.xdnf.cn/news/555373.html

相关文章:

  • 第40天-Python开发音乐播放器完整指南
  • 左右边界策略
  • 前端读取本地项目中 public/a.xlsx 文件中的数据 vue3
  • Linux管道工具
  • 全能签软件的由来和介绍
  • MRVG-Net论文精读
  • Linux周测(一)
  • 龙虎榜——20250520
  • vue3+elementPlus穿梭框拖拽
  • MONA:5%参数微调超越全量微调,CVPR2025新型视觉适配器
  • Linux学习心得问题整理(二)
  • 工业智能网关在工业锅炉安全监控中的组网配置指南
  • C++ QT 与 win32 窗口可以互操作
  • HarmonyOS5云服务技术分享--ArkTS开发函数
  • SpringBootDay1|面试题
  • 环特生物董事长汤珣、执行总经理张勇赴白云美湾国际化妆品研究院集群考察调研
  • ES6核心特性与语法
  • HarmonyOS5云服务技术分享--ArkTS调用函数
  • DAY 30 超大力王爱学Python
  • 2025最新的自动化测试面试题【答案+文档】
  • protobuf原理和使用
  • 接口测试速成指南:基础知识+工具使用全解析
  • 如何使用通义灵码提高前端开发效率
  • 2W+安全事件警示:10次数据泄露,6次与“人”有关
  • GESP2024年12月认证C++二级( 第三部分编程题(1)寻找数字)
  • [python] 轻量级定时任务调度库schedule使用指北
  • 阿里云百炼(1) : 阿里云百炼应用问答_回答图片问题_方案1_提问时上传图片文件
  • 一文深度解析:Pump 与 PumpSwap 的协议机制与技术差异
  • 如何理解大模型的幻觉输出及RAG技术的应用与实战案例
  • 批量替换文字