FreeRTOS的递归互斥锁

在FreeRTOS中,递归互斥锁(Recursive Mutex)是一种特殊类型的互斥锁,允许同一个任务多次获取锁而不会导致死锁。配置和使用递归互斥锁的步骤如下:


### 1. 配置FreeRTOS


确保你的FreeRTOS配置文件(通常是`FreeRTOSConfig.h`)中启用了互斥锁功能。通常情况下,这个功能是默认启用的,但你可以检查以下配置项:

#define configUSE_MUTEXES 1


### 2. 创建递归互斥锁


使用`xSemaphoreCreateRecursiveMutex`函数创建一个递归互斥锁。

#include "FreeRTOS.h"
#include "semphr.h"

// 创建递归互斥锁
SemaphoreHandle_t xRecursiveMutex;

void createRecursiveMutex() {
    xRecursiveMutex = xSemaphoreCreateRecursiveMutex();
    if (xRecursiveMutex == NULL) {
        // 处理创建失败的情况
    }
}


### 3. 获取递归互斥锁


使用`xSemaphoreTakeRecursive`函数获取递归互斥锁。


                
### FreeRTOS 中任务互斥锁的使用方法 在 FreeRTOS 中,任务互斥锁(Mutex)主要用于保护共享资源,防止多个任务同时访问该资源而导致数据不一致或其他竞争条件。以下是关于如何正确使用任务互斥锁的关键点: #### 1. 创建互斥锁 要使用互斥锁,首先需要通过 `xSemaphoreCreateMutex()` 函数创建它。这个函数会返回一个句柄,后续的操作都需要基于这个句柄来进行。 ```c SemaphoreHandle_t xMutex; xMutex = xSemaphoreCreateMutex(); if (xMutex == NULL) { // 错误处理逻辑:无法创建互斥锁 } ``` 如果成功创建,则可以继续使用该互斥锁[^1]。 #### 2. 获取互斥锁 当某个任务需要访问受保护的共享资源时,必须先尝试获取互斥锁。这可以通过调用 `xSemaphoreTake()` 实现。`xSemaphoreTake()` 的第二个参数是一个超时时间,表示任务等待获取互斥锁的最大时间间隔。 ```c if (xSemaphoreTake(xMutex, pdMS_TO_TICKS(10)) != pdTRUE) { // 处理未能获得互斥锁的情况 } // 访问共享资源 ``` 只有当前持有互斥锁的任务才能再次获取它而不会阻塞自己,这种特性称为 **递归所有权** 或者 **嵌套计数**[^3]。 #### 3. 释放互斥锁 完成对共享资源的访问之后,应该立即释放互斥锁以便其他任务能够获取并使用该资源。这是通过调用 `xSemaphoreGive()` 来实现的。 ```c xSemaphoreGive(xMutex); ``` 需要注意的是,在任何情况下都应确保互斥锁被正确释放,即使发生错误或者异常情况也一样。通常建议将释放操作放在 finally 块中(对于 C++),或采用类似的结构化编程方式来保障这一点[^2]。 #### 4. 避免优先级倒置 FreeRTOS 提供了一种机制叫做 **优先级继承** (Priority Inheritance)。启用此功能后,如果高优先级任务因为低优先级任务持有了某互斥锁而被迫等待,则后者会被临时提升到前者相同的优先级级别直到其释放互斥锁为止。这样就可以有效避免长时间延迟带来的问题。 默认情况下,由 `xSemaphoreCreateMutex()` 所创建的标准型互斥支持上述提到的功能;但如果需要用到更高级别的控制比如静态分配内存池等特殊场景下,则可能考虑改用 `xSemaphoreCreateRecursiveMutex()` 及对应的一系列API集。 ### 示例代码展示完整的流程如下: ```c #include "freertos/semphr.h" static SemaphoreHandle_t xMutex; void vTaskFunction(void *pvParameters){ const TickType_t xMaxBlockTime = pdMS_TO_TICKS(10); while(1){ /* 尝试获取互斥锁 */ if(pdPASS == xSemaphoreTake(xMutex , xMaxBlockTime)){ /* 成功取得定,现在可以安全地访问临界区内的变量 */ // 对共享资源执行读写操作... /* 完成工作后记得及时解 */ xSemaphoreGive(xMutex ); }else{ // 超过指定时间内未得到,可在此处加入重试策略或者其他业务逻辑... } // 继续其余非关键部分的工作循环.... } } /* 初始化阶段初始化mutex */ void setup(){ xMutex=xSemaphoreCreateMutex (); if(NULL==xMutex ){ // 报告失败状况,并采取适当措施恢复运行环境。 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薇远镖局

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值