FreeRTOS互斥量保护临界资源

🍎引入

在FreeRTOS中,互斥量是一种用于保护共享资源的同步机制。它通过二进制信号量的方式,确保在任意时刻只有一个任务可以获取互斥量并访问共享资源,其他任务将被阻塞。使用互斥量的基本步骤包括创建互斥量、获取互斥量、访问共享资源和释放互斥量。互斥量在FreeRTOS中起到了重要的作用,保护共享资源的访问,提供了一种有效的同步机制,确保任务之间的协作和数据的一致性。

换句话说就是使用互斥量解决双线程之间数据耦合的问题,而互斥量(Mutex)是一种用于保护临界资源的同步机制,通过独占式访问确保多任务环境下数据的一致性和安全性。


🍐内部原理

  1. 独占访问控制 互斥量通过“谁持有,谁释放”的机制,确保同一时刻仅有一个任务能访问临界资源。当任务A获取互斥量后,其他任务必须等待其释放才能继续操作。按照韦东山老师的话来说,就是谁抢占就干掉谁,在获取互斥量之后,会在底层关闭相应的任务调度或者是中断访问,以确保互斥量task获取到cpu资源

  2. 优先级继承机制 当高优先级任务因低优先级任务持有互斥量而阻塞时,系统会临时提升低优先级任务的优先级至高优先级任务的同级,避免优先级反转问题(如任务H等待任务L释放资源时,任务M抢占L导致H长时间阻塞)

  3. 递归互斥量支持 递归互斥量允许同一任务多次获取锁(需对应次数的释放),适用于需要重复访问临界资源的场景,但需注意避免死锁


🍌互斥量的使用

需要注意的是互斥量不能在中断服务函数(ISR)中使用,需改用信号量或直接屏蔽中断,然后是使用后需要即使释放避免死锁出现

  1. 创建互斥量

  • 动态创建

     SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();

    需先在FreeRTOSConfig.h中启用configSUPPORT_DYNAMIC_ALLOCATION,当然你也可以在stm32cubemx上配置简单快捷

  • 静态创建

     StaticQueue_t xStaticMutex;
     SemaphoreHandle_t xMutex = xSemaphoreCreateMutexStatic(&xStaticMutex);

    需预先分配静态内存并启用configSUPPORT_STATIC_ALLOCATION,中间件的配置同上,建议在cubemx上进行配置,因为使用cubemx创建的项目在重新生成时会初始化自定义的中间件配置

  1. 获取与释放互斥量

  • 获取互斥量

     if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
         // 访问临界资源
     }

    portMAX_DELAY表示无限等待,也可设置超时时间

  • 释放互斥量

     xSemaphoreGive(xMutex);

    仅持有者可释放,否则可能导致死锁

  1. 删除互斥量

 vSemaphoreDelete(xMutex);

🍒互斥量对临界资源的保护

在访问共享资源(如全局变量、外设)前加锁,确保操作的原子性。通过优先级继承机制,临时提升低优先级任务的优先级,减少高优先级任务阻塞时间

 void Task1(void *pvParameters) {
     xSemaphoreTake(xMutex, portMAX_DELAY);
     sharedCounter++;  // 临界区操作
     xSemaphoreGive(xMutex);
 }

若任务需多次访问同一资源,使用递归互斥量(xSemaphoreCreateRecursiveMutex)避免自锁问题。另外临界区代码应尽量简短,避免长时间占用互斥量导致系统实时性下降,如出现占用cpu资源进行长时间的SPI通信


🍅与二值信号量对比

在FreeRTOS中,互斥量(Mutex)二值信号量(Binary Semaphore)均基于二值状态(0或1)实现任务同步,但它们的设计目标、功能特性及适用场景存在显著差异

本质:互斥量是二值信号量的plus版 互斥量本质上是具有优先级继承机制所有权管理的特殊二值信号量。其底层实现通常基于队列(FreeRTOS通过xQueueCreateMutex()创建),但通过额外机制优化了互斥场景下的任务调度。而反观二值信号量,仅用于任务或中断间的同步(如事件通知),不涉及资源所有权管理,也无法解决优先级反转问题

当高优先级任务因低优先级任务持有互斥量而阻塞时,系统会临时提升低优先级任务的优先级至高优先级任务的同级,避免中间优先级任务抢占,从而减少阻塞时间,很好的解决了信号量出现的优先级反转问题


🍅优先级反转问题

在FreeRTOS中,二值信号量(Binary Semaphore)本身并不直接支持优先级继承机制,因此在使用信号量进行任务同步时,可能发生优先级反转问题。这一问题与互斥量(Mutex)的场景类似,但信号量缺乏内置的优先级继承机制,导致其风险更高。

举个例子就是,当24和26优先级的任务同时使用一个信号量,而24的优先级先执行,然后碰到25优先级的任务出来抢占cpu资源一直运行,而此时26优先级的任务想来执行发现没有信号量被阻塞,这就是优先级反转

🍈总结

互斥量就是一种特殊的信号量,解决了信号量优先级反转的问题,同时实现对临界资源的互斥访问

那么以上就是我对于互斥量保护临界资源的一些理解,如有叙述的不正确的地方请指正

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇