10.FreeRTOS_互斥量

互斥量概述

在博文“ FreeRTOS_信号量 ”中,使用了二进制信号量实现了互斥,保护了串口资源。博文链接如下:

FreeRTOS_信号量-优快云博客

但还是要引入互斥量的概念。互斥量与二进制信号量相比,能够多实现如下两个功能:

  • 防止优先级反转问题
  • 解决递归上锁/解锁问题

互斥量有两种:

  • 普通互斥量:具有优先级继承功能,解决优先级反转问题
  • 递归锁:具有优先级继承功能、能够解决递归上锁/解锁问题、解决谁上锁谁才能解锁的问题

优先级反转

优先级反转问题

假设任务A、B、C的优先级为1、2、3。在程序开始时,A进行上锁,之后B运行抢断的A,之后C运行抢断了B。在C中,想获得锁,但A已经上锁,所以C进入了阻塞,释放了CPU。这时B继续运行,但不解锁,从而导致C被B抢占,即高优先级的任务是否能继续执行由低优先级的任务决定。

这种现象称为优先级反转。

优先级继承

使用优先级继承的方法解决优先级反转的问题。

在C获得锁之后进入阻塞状态,同时执行上锁的任务A会继承C的优先级3,从而进行执行。当A执行完解锁后,A优先级的优先级变回原来的优先级1。之后C获得锁,不再阻塞,C继续执行,执行完成之后,B运行。

在低优先级任务上锁,高优先级任务获得锁阻塞之后,低优先级任务继承高优先级任务的优先级的操作叫做优先级继承。

递归上锁/解锁

递归上锁原因

递归上锁的示例代码如下:

void fun(){
	xSemaphoreTake(SemaphoreHandleTest,portMAX_DELAY);/* 上锁 */
	/* 一些功能 */
	xSemaphoreGive(SemaphoreHandleTest);/* 解锁 */
}
void Task1(void *param){
	while(1){
		xSemaphoreTake(SemaphoreHandleTest,portMAX_DELAY);/* 上锁 */
		/* 一些功能 */
		fun();
		xSemaphoreGive(SemaphoreHandleTest);/* 解锁 */
	}
}

在上述代码中,任务1首先进行了上锁,之后调用了fun函数。在fun函数中又进行了上锁,但这时已经上锁,所以就阻塞在了fun函数中。最终导致Task1无法执行完成fun函数,也就无法执行解锁函数,形成死锁。

递归锁

使用递归锁可以解决上述问题。递归锁的作用是,如果开始时为A来上锁,那么在上锁之后,A依旧可以进行调用上锁函数进行上锁,而不会进入阻塞状态。但不管怎样,上锁之后都要解锁,即:上锁多少次,就要解锁多少次,上锁与解锁一 一配对。

除此之外,递归锁还可以满足谁上锁,谁才有权力解锁的问题。而信号量和普通互斥锁并不能实现这个功能。

相关配置

在使用互斥量之前,需要打开宏开关,具体的步骤如下:

在使用递归锁之前,需要打开宏开关,具体的步骤如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值