目录
1.2.1 函数 xSemaphoreCreateRecursiveMutex()
1.2.2 函数 xSemaphoreCreateRecursiveMutexStatic()
1. 递归互斥信号量
1.1 递归互斥信号量简介
递归互斥信号量可以看作是一个特殊的互斥信号量,已经获取了互斥信号量的任务就不能再次获取这个互斥信号量,但是递归互斥信号量不同,已经获取了递归互斥信号量的任务可以再次获取这个递归互斥信号量,而且次数不限!一个任务使用函数 xSemaphoreTakeRecursive() 成功的获取了多少次递归互斥信号量就得使用函数 xSemaphoreGiveRecursive() 释放多少次!比如某个任务成功的获取了 5 次递归信号量,那么这个任务也得同样的释放 5 次递归信号量。
递归互斥信号量也有优先级继承的机制,所以当任务使用完递归互斥信号量以后一定要记得释放(如果不释放那么低优先级的任务的优先级将永远和高优先级任务保持一致)。同互斥信号量一样,递归互斥信号量不能用于中断服务函数中。
由于优先级继承的存在,就限定了递归互斥信号量只能用在任务中,不能用在中断服务函数中!
中断服务函数不能设置阻塞时间。
要使用递归互斥信号量的话宏 configUSE_RECURSIVE_MUTEXES 必须为 1 !
1.2 创建互斥信号量
FreeRTOS 提供了两个递归互斥信号量创建函数:
函数:
xSemaphoreCreateRecursiveMutex() 使用动态方法创建递归互斥信号量
xSemaphoreCreateRecursiveMutexStatic() 使用静态方法创建递归互斥信号量
1.2.1 函数 xSemaphoreCreateRecursiveMutex()
此函数用于创建一个递归互斥信号量,所需要的内存通过动态内存管理方法分配。此函数本质是一个宏,真正完成信号量创建的是函数 xQueueCreateMutex(),此函数原型为:
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void)
参数:
无
返回值:
NULL: 互斥信号量创建失败。
其他值: 创建成功的互斥信号量的句柄。
1.2.2 函数 xSemaphoreCreateRecursiveMutexStatic()
此函数也是创建递归互斥信号量的,只不过使用此函数创建递归互斥信号量的话信号量所需要的 RAM 需要由用户来分配,此函数是个宏,具体创建过程是通过函数 xQueueCreateMutexStatic() 来完成的,函数原型如下:
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t *pxMutexBuffer)
参数:
pxMutexBuffer: 此参数指向一个 StaticSemaphore_t 类型的变量,用来保存信号量结构体。
返回值:
NULL: 互斥信号量创建失败。
其他值: 创建成功的互斥信号量的句柄。
2. 使用示例
SemaphoreHandle_t RecursiveMutex; //递归互斥信号量句柄
//某个任务中创建一个递归互斥信号量
void vATask(void* pvParameters)
{
//必须创建递归互斥信号量才可以使用
RecursiveMutex = xSemaphoreCreateRecursiveMutex(); //创建递归互斥信号量
for(;;)
{
//任务代码
}
}
//任务调用的使用递归互斥信号量的功能函数
void vAFunction(void)
{
//其他处理代码
if(xMutex!=NULL)
{
//获取递归互斥信号量,阻塞时间为10个节拍
if(xSemaphoreTakeRecursive(RecursiveMutex,10)==pdTRUE)
{
xSemaphoreTakeRecursive(RecursiveMutex,(TickType_t)10);
xSemaphoreTakeRecursive(RecursiveMutex,(TickType_t)10);
//任务获取了三次递归互斥信号量,必须也要释放三次
xSemaphoreGiveRecursive(RecursiveMutex);
xSemaphoreGiveRecursive(RecursiveMutex);
xSemaphoreGiveRecursive(RecursiveMutex);
}
}
else
{
//递归互斥信号量获取失败
}
}