FreeRTOS笔记-互斥量

  1. 互斥量
    1. 对互斥量的理解
    2. 对互斥量的常规使用
    3. 递归锁

互斥量

对互斥量的理解

二进制信号量的互斥,容易导致死锁。即一个任务锁住后继续运行,在运行过程中再次请求解锁,导致后续没解锁信息无法继续下去,造成死锁。

  • 比喻: 我要有工作经验的(锁住直到有工作经验的来才给工作)
  • 我要工作才能有工作经验(请求工作不成功,不运行不达到条件)

递归锁:类似于嵌套,锁中锁 。

对互斥量的常规使用

互斥量创建。与信号量一样的句柄创建,函数运行后,初始值为1,不需要手动赋值。代码展示了创建串口通信1互斥量的代码

1
Semaphore_Handle_USART1 = xSemaphoreCreateMutex();

跟二进制信号量一样的赋值方法,give和take即可对锁进行操作。
但是二进制信号量的互斥锁会导致优先级反转,即高优先级任务在监测到互斥锁锁住时进入阻塞状态放弃CPU资源,低优先级的任务进行运行,如果低优先级的任务不放弃CPU资源,高优先级的任务便不能执行。为了解决这个问题,我们引入了互斥量优先级继承的功能。

优先级继承功能
Mutex有着优先级继承的属性,在高优先级的任务获取锁失败以后,
会将该高优先级任务的优先级赋给上锁的任务运行,即上锁的任务继承了高优先级任务的优先级。
当低优先级的任务放弃CPU资源时,重新给回高优先级任务继续运行,低优先级任务不再抢占高优先级任务,避免了优先级反转。

互斥量的缺陷
互斥量任何任务都可以对这个锁进行解锁,如果出现了其他任务强行解锁该锁就不能正常用了。这个使用引入递归锁。


递归锁

递归锁的创建

1
Semaphore_Handle_USART1 = xSemaphoreCreateRecursiveMutex();

递归锁的读取和释放

1
2
xSemaphoreTakeRecursive(Semaphore_Handle_USART1, portMAX_DELAY);
xSemaphoreGiveRecursive(Semaphore_Handle_USART1);

递归锁的可嵌套性,在任务中得到了锁的使用权,那么在里面任然拥有该权限,可以嵌套上锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Task3Function(void * param)
{
int i;
while(1)
{
xSemaphoreTakeRecursive(Semaphore_Handle_USART1, portMAX_DELAY);
printf("task3 is running\r\n");
for(i = 0; i < 10; i++)
{
xSemaphoreTakeRecursive(Semaphore_Handle_USART1, portMAX_DELAY);
printf("task3 is running loop times:%d\r\n", i);
xSemaphoreGiveRecursive(Semaphore_Handle_USART1);
}
xSemaphoreGiveRecursive(Semaphore_Handle_USART1);
vTaskDelay(1);
}
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1186703947@qq.com

💰

×

Help us with donation

相册 动态菜单1