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

【详细】FreeRTOS任务的内部机制

一.结构体

volatile StackType_t * pxTopOfStack:保存当前任务堆栈的栈顶指针。

ListItem_t xStateListItem:用于将任务挂接到各种调度状态链表中。

ListItem_t xEventListItem:当任务因等待某个同步/通信对象(队列、信号量、互斥量、事件组等)而被阻塞时,内核会通过 xEventListItem 把任务挂接到该对象的 等待事件列表上。

UBaseType_t uxPriority:任务的调度优先级,0 为最低优先级。

StackType_t * pxStack:指向任务堆栈的起始地址(栈底)。

char pcTaskName[ configMAX_TASK_NAME_LEN ]:任务的描述性名称,仅用于调试(如 vTaskList() 输出),不参与调度逻辑。

二.创建

TaskFunction_t pxTaskCode:函数指针
const char * const pcName:函数名称
const configSTACK_DEPTH_TYPE usStackDepth:栈的大小
void * const pvParameters:函数参数
UBaseType_t uxPriority:任务优先级
TaskHandle_t * const pxCreatedTask :传出来的任务句柄,指向的TCB结构体

这里要注意一点的是,为什么创建任务的参数和TCB结构体对不上?多了函数指针和函数参数呢?

当调度器首次切换到该任务时,会从栈中“恢复”这些寄存器值,于是 CPU 就会直接跳转到该函数,并以 R0 中的值作为参数开始执行。所以,函数指针和参数是在栈里,而不是在 TCB 的成员中。

另外,任务创建完成后,内核会把新任务的 xStateListItem 插入到对应优先级的就绪链表 pxReadyTasksLists[ uxPriority ] 中。如果此时没有更高优先级的任务,pxCurrentTCB 会指向这个新任务,这样调度器在下一轮调度时就会先执行它。

三.调度

优先级与状态

  • 优先级不同

    • 高优先级的任务,优先执行,可以抢占低优先级的任务

    • 高优先级的任务不停止,低优先级的任务永远无法执行

    • 同等优先级的任务,轮流执行:时间片轮转

  • 状态

    • 运行态:running

    • 就绪态:ready

    • 阻塞:blocked,等待某件事(时间、事件)

    • 暂停:suspend,休息去了

  • 怎么管理?

    • 怎么取出要运行的任务?

      • 找到最高优先级的运行态、就绪态任务,运行它

      • 如果大家平级,轮流执行:排队,链表前面的先运行,运行1个tick后乖乖地去链表尾部排队

调度方法

  • 谁进行调度?

    • TICK中断!

  • 可抢占:高优先级的任务先运行

  • 时间片轮转:同优先级的任务轮流执行

  • 空闲任务礼让:如果有同是优先级0的其他就绪任务,空闲任务主动放弃一次运行机会

四.重点

怎么调度切换任务呢?最重要的核心就是这个PendSVHandler。

1.保存当前任务上下文

2.选择下一个要执行的任务

3.恢复新任务上下文并返回

找出当前优先级最高的就绪任务,并将其 TCB 赋值给 pxCurrentTCB

2个版本:

#define taskSELECT_HIGHEST_PRIORITY_TASK() \ { \ UBaseType_t uxTopPriority = uxTopReadyPriority; \ /* 从最高优先级向下找第一个非空的就绪链表 */ \ while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ { \ configASSERT( uxTopPriority ); \ --uxTopPriority; \ } \ /* 取出该链表中的下一个任务,实现时间片轮转 */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ uxTopReadyPriority = uxTopPriority; \ } /*---------------------------------------------------------------------------------------*/ #define taskSELECT_HIGHEST_PRIORITY_TASK() \ { \ UBaseType_t uxTopPriority; \ /* 1. 从位图中直接得到最高就绪优先级数值 */ \ portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ /* 2. 确保该优先级的就绪列表非空(调试断言) */ \ configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ /* 3. 从该优先级链表中取出下一个任务交给 pxCurrentTCB */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ }
http://www.jsqmd.com/news/1257242/

相关文章:

  • SharpKeys终极指南:解决Windows键位映射延迟的完整方案
  • 广州快消消费品牌企业做GEO服务商怎么选?2026靠谱选型指南与五家代表性服务商深度测评 - 小随科技
  • 社交泛娱乐出海如何抓住AIGC?我在融云WICC上看到了答案
  • 从零开始掌握微信好友自动化添加工具:高效批量添加解决方案
  • 广州软件SaaS企业做GEO服务商怎么选?2026年五家代表性机构靠谱选型指南 - 小随科技
  • AI生图总是“多一只手”?教你如何用 Negative Prompt(反向提示词)拯救画面
  • 2026汽车钣金加工砂纸厂家盘点:金相检测砂纸生产厂家+汽车油漆打磨砂纸厂家+汽车轮毂轮纸生产厂家+汽车维修砂纸厂家推荐 - 栗子测评
  • 2026北京卡地亚回收哪家口碑好?尚典蓝气球鉴定实力过硬,这份本地测评榜单给出答案 - 奢品流通笔谈
  • GLM-OCR轻量级专业模型部署与优化指南
  • 爽提:以“高效智能”赋能“高校传统”食堂运营转型升级
  • Diablo Edit2终极指南:5分钟完成暗黑2角色定制,彻底告别枯燥刷怪
  • RAG系统的工程化之路:检索、生成与质量评估
  • 广州本地生活服务企业做GEO服务商怎么选?2026靠谱选型指南与五家代表性服务商深度测评 - 科技快讯
  • 广州人力资源服务企业做GEO服务商怎么选?2026年本地靠谱选型指南与五家服务商深度测评 - 小随科技
  • 5分钟零成本搭建:如何用AI股票分析工具让投资决策更简单?
  • 如何为你的 AI 漫剧设计一个让人一眼记住的“反派角色”?
  • AI 为什么总喜欢写防御性代码?
  • FreeRTOS临界资源访问方法
  • Unity3D协程的使用
  • 车衣防晒膜建筑遮阳膜座椅镀膜厂家哪家好?2026欧德龙(杭州保通科技实业有限公司)靠谱功能膜甄选:汽车车衣生产制造/车窗 - 栗子测评
  • DETR训练实践以及自动预标注脚本、测试可视化脚本
  • 2026英语培训行业口碑靠谱知名GEO优化公司筛选与推荐 头部服务商对比+合作避坑全指南 - 行业观察网
  • 2026年7月海尔冰箱全国统一24小时售后服务专属热线电话公示最新说明 - 全国网点服务中心
  • MLOps 弹性伸缩:自动扩缩容与 GPU 利用率优化
  • 多轮对话系统崩溃前夜:3个被90%团队忽略的提示词设计漏洞及紧急修复指南
  • 旧运动服回收靠谱吗?爱宝拉高价上门免费取件真相揭秘 - 快递物流资讯
  • 2026 年 7 月新发布:益阳正规的百鸟展企业哪家好,揭秘自然界最震撼的鸟类奇观-振豪特种养殖 - 企业推荐官【认证】
  • SpringBoot 3 入门实战:从环境搭建到打包部署
  • AI技术空转破解:从评估指标到工程落地的实践指南
  • 工业与AI融合应用 | 7大核心用例落地:AI如何破解半导体研发周期长、良率低难题