FreeRTOS学习(十七)——优先级翻转与优先级继承 上一节学习了互斥量Mutex它可以保护共享资源保证同一时刻只有一个任务能够访问串口、LCD、Flash等资源。但是如果多个不同优先级的任务同时竞争一个互斥量就可能产生一个比较隐蔽的问题——优先级翻转Priority Inversion。这一节学习什么是优先级翻转以及FreeRTOS是如何利用**优先级继承Priority Inheritance**解决这一问题的。这也是嵌入式软件工程师面试中经常出现的知识点。一、什么是优先级翻转假设系统中有三个任务Task_H 高优先级3Task_M 中优先级2Task_L 低优先级1其中Task_L首先获得了互斥量Mutex开始访问串口。此时Task_H也需要访问串口。但是Mutex已经被Task_L占用因此Task_H ↓ 等待Mutex按理来说只需要等待Task_L执行完释放互斥量即可。但是Task_M此时变为就绪态。由于Task_M 优先级 Task_L于是CPU开始执行Task_M而Task_L一直得不到CPU。结果就是Task_H ↓ 等待Task_L ↓ Task_L又一直被Task_M抢占最终高优先级任务 反而等待低优先级任务。这就是优先级翻转二、优先级翻转过程整个过程可以表示为Task_L 获得Mutex ↓ Task_H需要Mutex ↓ Task_H阻塞 ↓ Task_M开始运行 ↓ Task_L没有机会运行 ↓ Mutex一直不能释放 ↓ Task_H持续等待可以看到真正阻塞高优先级任务的不是Task_L而是Task_M这也是优先级翻转最容易让人困惑的地方。三、为什么优先级翻转危险假设Task_H负责电机控制而Task_M只是LED闪烁如果发生优先级翻转LED任务 一直抢占CPU ↓ 电机控制一直等待显然是不合理的。在实时系统中高优先级任务 必须尽快得到CPU。因此必须解决优先级翻转问题。四、什么是优先级继承FreeRTOS互斥量支持Priority Inheritance即优先级继承。它的思想很简单当Task_H等待Mutex而Mutex被Task_L占有时。FreeRTOS会暂时把Task_L的优先级提升为Task_H的优先级。例如原来Task_L Priority 1现在自动变成Priority 3这样Task_M Priority 2就不能抢占Task_L了。五、优先级继承过程加入优先级继承以后Task_L获得Mutex ↓ Task_H等待Mutex ↓ Task_L优先级提升 ↓ Task_L继续运行 ↓ 释放Mutex ↓ Task_L恢复原优先级 ↓ Task_H立即运行整个过程中Task_M不会再影响Task_H等待互斥量。因此优先级翻转被解决。六、代码示例创建互斥量SemaphoreHandle_t Mutex; Mutex xSemaphoreCreateMutex();任务1void LowTask(void *pvParameters) { while(1) { xSemaphoreTake( Mutex, portMAX_DELAY ); printf(Low Task\r\n); vTaskDelay(pdMS_TO_TICKS(2000)); xSemaphoreGive(Mutex); vTaskDelay(pdMS_TO_TICKS(1000)); } }任务2void HighTask(void *pvParameters) { while(1) { xSemaphoreTake( Mutex, portMAX_DELAY ); printf(High Task\r\n); xSemaphoreGive(Mutex); vTaskDelay(pdMS_TO_TICKS(500)); } }程序运行过程中如果LowTask已经获得互斥量。随后HighTask请求同一个互斥量。FreeRTOS会自动进行优先级继承。整个过程不需要用户手动修改优先级。七、为什么二值信号量不能解决很多初学者容易认为二值信号量 ↓ 也能锁资源。事实上二值信号量 没有优先级继承。因此如果使用xSemaphoreCreateBinary();保护共享资源。发生优先级翻转以后。FreeRTOS不会自动提高低优先级任务的优先级。所以保护共享资源 推荐使用Mutex 不要使用Binary Semaphore。八、什么时候会发生优先级翻转通常需要满足三个条件第一多个任务优先级不同。第二多个任务共同访问同一个共享资源。第三共享资源采用互斥机制保护。例如USART SPI I2C Flash SD卡这些都是实际工程中经常发生优先级翻转的地方。九、实际工程建议互斥量虽然能够解决优先级翻转但仍然要尽量缩短Take ↓ Give之间的代码。例如xSemaphoreTake(); printf(); xSemaphoreGive();是合理的。但是xSemaphoreTake(); vTaskDelay(5000); xSemaphoreGive();则不建议这样写。因为任务长时间占有互斥量会增加其他任务等待时间降低系统实时性。因此共享资源保护范围越小越好互斥量占用时间越短越好。十、总结这一节学习了FreeRTOS中的优先级翻转与优先级继承。当高优先级任务等待低优先级任务占有的互斥量而低优先级任务又被中优先级任务抢占时就会发生优先级翻转。FreeRTOS互斥量支持优先级继承机制能够临时提高持有互斥量任务的优先级使其尽快释放共享资源从而减少高优先级任务的等待时间。因此需要牢记二值信号量用于任务同步。互斥量用于共享资源保护。互斥量具有优先级继承而二值信号量没有。

相关新闻

最新新闻

告别“ID跳变”痛点:全域无感定位追踪技术,实现石化厂区人员、车辆跨镜头连续稳定跟踪

告别“ID跳变”痛点:全域无感定位追踪技术,实现石化厂区人员、车辆跨镜头连续稳定跟踪

告别“ID跳变”痛点:全域无感定位追踪技术,实现石化厂区人员、车辆跨镜头连续稳定跟踪一、行业痛点:石化复杂工况下,传统追踪方案深陷ID跳变、轨迹断链困局石化厂区囊括炼化装置区、储罐区、密闭管廊、装卸站台、厂区主干道等全域…

2026/8/5 10:03:01
UE4蓝图空间变换核心:Get/Set Actor Location深度解析与实战应用

UE4蓝图空间变换核心:Get/Set Actor Location深度解析与实战应用

1. 项目概述:蓝图空间变换的基石 在虚幻引擎4(UE4)的蓝图可视化脚本世界里,物体的空间变换是几乎所有交互和动态效果的基石。无论是让一个角色移动,让一扇门打开,还是让一个宝箱在玩家靠近时微微上浮&#…

2026/8/5 10:03:01
虚拟电厂“牌照“及准入门槛

虚拟电厂“牌照“及准入门槛

虚拟电厂"牌照"所谓"VPP 牌照" 新型经营主体注册资格 能力测试达标 公示生效。它不等于售电牌照,但参与电能量市场时须叠加售电资质。环节性质依据电力业务许可证豁免国能发法改〔2024〕93 号电力市场注册注册制(申请—承诺—审查…

2026/8/5 10:03:01
GULP:宇宙的演化---第2章光速不变原理

GULP:宇宙的演化---第2章光速不变原理

第二章 光速不变原理 1. 承接第一章 第一章我们讨论了动量守恒定律。它告诉我们,一个系统在不受外力时,总动量保持不变。在GULP框架中,这意味着系统在变化中仍然保有一个不变的约束——零Bug度并不是说系统永远不变化,而是说系统在…

2026/8/5 10:03:01
Android进程被杀全链路分析:从am_proc_died到内存泄漏排查实战

Android进程被杀全链路分析:从am_proc_died到内存泄漏排查实战

1. 从一次线上崩溃说起:为什么你的App进程会“神秘消失”?那天下午,我正在悠闲地喝着咖啡,突然手机上的监控告警像疯了一样响个不停。告警信息很明确:我们核心App的日活用户留存曲线,在某个时间点之后出现了…

2026/8/5 10:03:01
解决Ubuntu 22.04虚拟机共享文件夹问题:vmhgfs-fuse与systemd挂载配置

解决Ubuntu 22.04虚拟机共享文件夹问题:vmhgfs-fuse与systemd挂载配置

1. 问题场景与核心矛盾如果你正在用VMware Workstation或VMware Player跑Ubuntu 22.04,大概率会遇到一个经典又恼人的问题:明明在虚拟机设置里勾选了“共享文件夹”,路径也指定了,Windows宿主机的文件夹看起来一切就绪&#xff0c…

2026/8/5 9:58:01