STM32 | FreeRTOS 递归信号量

递归信号量

一、概述

互斥量的使用比较单一,因为它是信号量的一种,并且它是以锁的形式存在。在初始化的时候,互斥量处于开锁的状态,而被任务持有的时候则立刻转为闭锁的状态。

递归类型的互斥量可以被拥有者重复获取。拥有互斥量的任务必须调用API函数xSemaphoreGiveRecursive()将拥有的递归互斥量全部释放后,该信号量才真正被释放。比如,一个任务成功获取同一个互斥量5次,那么这个任务要将这个互斥量释放5次之后,其它任务才能获取到它。递归互斥信号量,其实就是互斥信号量里面嵌套互斥信号量,示例如下:

复制代码
static void vTaskMsgPro(void *pvParameters){TickType_t xLastWakeTime;const TickType_t xFrequency = 1500;/* 获取当前的系统时间 */xLastWakeTime = xTaskGetTickCount();while(1){/* 递归互斥信号量,其实就是互斥信号量里面嵌套互斥信号量 */xSemaphoreTakeRecursive(xRecursiveMutex, portMAX_DELAY);{/* -------------------------------------- *///假如这里是被保护的资源,第1层被保护的资源,用户可以在这里添加被保护资源/* ---------------------------------------------------------------------------- */printf("任务vTaskMsgPro在运行,第1层被保护的资源,用户可以在这里添加被保护资源\r\n");/* 第1层被保护的资源里面嵌套被保护的资源 */xSemaphoreTakeRecursive(xRecursiveMutex, portMAX_DELAY);{/* ------------------------------------------------------------------------ *///假如这里是被保护的资源,第2层被保护的资源,用户可以在这里添加被保护资源/* ------------------------------------------------------------------------ */printf("任务vTaskMsgPro在运行,第2层被保护的资源,用户可以在这里添加被保护资源\r\n");/* 第2层被保护的资源里面嵌套被保护的资源 */xSemaphoreTakeRecursive(xRecursiveMutex, portMAX_DELAY);{printf("任务vTaskMsgPro在运行,第3层被保护的资源,用户可以在这里添加被保护资源\r\n");}xSemaphoreGiveRecursive(xRecursiveMutex);}xSemaphoreGiveRecursive(xRecursiveMutex);    }xSemaphoreGiveRecursive(xRecursiveMutex);/* vTaskDelayUntil是绝对延迟,vTaskDelay是相对延迟。*/vTaskDelayUntil(&xLastWakeTime, xFrequency);}}

二、配置

使能递归互斥量,详细文件在FreeRTOS.h。

文件路径:FreeRTOS.h

复制代码
#ifndef configUSE_RECURSIVE_MUTEXES#define configUSE_RECURSIVE_MUTEXES 1#endif

三、函数接口

1.创建递归互斥量

复制代码
#if((configSUPPORT_DYNAMIC_ALLOCATION==1) && (configUSE_RECURSIVE_MUTEXES ==1))#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )#endif

参数:无

返回值:

如果创建成功则返回一个递归互斥量句柄,用于访问创建的递归互斥量。如果创建不成功则返回 NULL。

2.获取递归互斥量

复制代码
#if( configUSE_RECURSIVE_MUTEXES == 1 )#define xSemaphoreTakeRecursive( xMutex, xBlockTime )xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )#endif

参数:

  1. tick(即系统节拍周期)。如果

宏 INCLUDE_vTaskSuspend 定义为 1 且形参 xTicksToWait 设置为portMAX_DELAY ,则任务将一直阻塞在该递归互斥量上(即没有超时时间)。

返回值:

获取成功则返回 pdTRUE,在超时之前没有获取成功则返回 errQUEUE_EMPTY。

3.释放递归互斥量

复制代码
#if( configUSE_RECURSIVE_MUTEXES == 1 )#define xSemaphoreGiveRecursive( xMutex ) \xQueueGiveMutexRecursive( ( xMutex ) )#endif

参数:

返回值:

成功,pdPASS

失败,pdFAIL

四、示例代码

复制代码
1.freertos.cstatic void app_task1(void* pvParameters){for(;;){//获取递归互斥信号量xSemaphoreTakeRecursive(MutexSemaphore, portMAX_DELAY);{printf("app_task1 is running 1...\r\n");//获取递归互斥信号量xSemaphoreTakeRecursive(MutexSemaphore, portMAX_DELAY);{printf("app_task1 is running 2...\r\n");//获取递归互斥信号量xSemaphoreTakeRecursive(MutexSemaphore, portMAX_DELAY);{printf("app_task1 is running 3...\r\n");}//释放递归互斥信号量xSemaphoreGiveRecursive(MutexSemaphore); }//释放递归互斥信号量  xSemaphoreGiveRecursive(MutexSemaphore);  }  //释放递归互斥信号量xSemaphoreGiveRecursive(MutexSemaphore);  vTaskDelay(300);  }} static void app_task2(void* pvParameters){for(;;){//获取递归互斥信号量xSemaphoreTakeRecursive(MutexSemaphore, portMAX_DELAY);{printf("app_task2 is running 1...\r\n");//获取递归互斥信号量xSemaphoreTakeRecursive(MutexSemaphore, portMAX_DELAY);{printf("app_task2 is running 2...\r\n");//获取递归互斥信号量xSemaphoreTakeRecursive(MutexSemaphore, portMAX_DELAY);{printf("app_task2 is running 3...\r\n");}//释放递归互斥信号量xSemaphoreGiveRecursive(MutexSemaphore); }//释放递归互斥信号量  xSemaphoreGiveRecursive(MutexSemaphore);  }  //释放递归互斥信号量xSemaphoreGiveRecursive(MutexSemaphore);  vTaskDelay(200);}} 

演示

相关推荐
IT_Octopus3 小时前
【零基础入门 LLM 开发 · Day 13】:LangChain 的对话记忆——Message 对象版
人工智能·python·langchain
2603_965148113 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
CCblandy5 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
Cc.Y6 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python
Tronlong创龙6 小时前
SBC‑TLT153 嵌入式 Linux 应用开发,交叉编译与 GDB 调试实践(上)
嵌入式硬件·嵌入式开发·硬件开发·工业控制·工业开发板
拿本唠嗑AI研究6 小时前
本体工程实战指南:从建模到可维护的完整落地路径
java·人工智能·python·jena·ontology
Smoothcloud润云6 小时前
PyTorch推理服务模型热切换与失败回滚实战:降低版本更新中断
服务器·人工智能·pytorch·python·深度学习·gpu
巴渝小禹6 小时前
单片机死循环delay_us()计算方法
单片机·嵌入式硬件
Yiran_G6 小时前
LoRa串口模组和SoC模组怎么选?从MCU架构看无线通信方案设计
嵌入式硬件·物联网
jsjzsl26 小时前
递归自改进系统(RSI)的本质是自发对称破缺:智能爆炸有界—— AI研发切记盲目投入
人工智能·python·算法