在基于rtos开发项目时,通常都会遇到互斥的情况,比如:几个任务都要使用一个uart串口进行发送数据。
如果不加互斥锁,优先级高的任务,会抢占串口并发送数据,则有可能会出现发送数据“乱码”的情况。
今天就说说在rtos开发中,互斥锁一个常见的问题。
什么是mutex互斥锁?
学习过rtos的读者应该对互斥不陌生,互斥锁就是为了避免任务之间互相抢占某种资源而设计的一种“锁”。
就如上面说的,一个串口,被两个任务抢占,如果不加锁,则会出现两个任务交叉发送数据,即“乱码”;
但是,如果加了互斥锁,则会等待其他任务发送完成之后才继续发送,保证了数据的完整(而不是乱码);
嵌入式专栏
2
mutex互斥锁例子
这里以三个任务、两个互斥锁为例,代码如下:
void task1(){ /*do something*/ osmutex1_pend(); //互斥锁1加锁 /*加锁处理事情*/ osmutex1_post(); //互斥锁1解锁}void task2(){ /*do something*/ osmutex1_pend(); //互斥锁1加锁 osmutex2_pend(); //互斥锁2加锁 /*加锁处理事情*/ osmutex2_post(); //互斥锁2解锁 osmutex1_post(); //互斥锁1解锁}void task3(){ /*do something*/ osmutex2_pend(); //互斥锁2加锁 /*加锁处理事情*/ osmutex2_post(); //互斥锁1解锁}
这样设计,大家看出问题了吗?
老司机应该看出来了,新手可能摸不着头脑。
在任务2中,进行了2次加锁、解锁,而且“环环相扣”。
mutex互斥锁问题
假如任务1、 任务2、 任务3优先级分别为:1、 2、 3。
优先级顺序就是:任务1 > 任务2 > 任务3(数字越小代表任务优先级越高)。
假设:任务1和任务2处于等待事件状态,也就是处于阻塞状态, task 3 处于运行状态。
当任务3在“加锁处理事情”的时候,任务2抢占了任务3(任务2挂起时间到了),此时任务3挂起,任务2处于运行状态;
如果任务2在“互斥锁1加锁”之后,任务1抢占了任务2,此时,任务1处于运行状态;
这个时候,你发现问题了没有?
任务1在执行“osmutex1_pend();”会等待“互斥锁1解锁”,如果其他方式没有对“互斥锁1解锁”,则会出现“死锁”的情况。
分享一张图片,你就会明白什么是死锁了:
解决办法
比如对任务2加锁方式进行改善:
void task2(){ /*do something*/ osmutex1_pend(); //互斥锁1加锁 /*do something*/ osmutex1_post(); //互斥锁1解锁 osmutex2_pend(); //互斥锁2加锁 /*do something*/ osmutex2_post(); //互斥锁1解锁}
或者对低优先级的任务3加锁方式进行改善:
void task3(){ /*do something*/ osmutex1_pend(); //互斥锁1加锁 osmutex2_pend(); //互斥锁2加锁 /*加锁处理事情*/ osmutex2_post(); //互斥锁2解锁 osmutex1_post(); //互斥锁1解锁}
出问题的原因, 当一个任务获得了临界区资源的锁,在没有释放这个锁的前提下又去获得另外一块临界区资源,这个时候就要引起足够的注意了,设计成败在于你是否彻底理解了之前的问题。 但是,归根到底这样的问题还是要求用户在设计阶段去避免,一个系统不可能是万能的,正确的设计才是最重要的。
小米立式风冷无线充30W明天到货 售价199元
GSMA eSIM如何提高物联网项目的灵活性和效率
Adreno GPU 矩阵乘法——第1讲:OpenCL优化
消费电子芯片与车规芯片两者有什么不同?
价格酣战将持续 中央空调未来或将成为决定空调品牌格局的胜负手
什么是Mutex互斥锁
高云半导体与ARM联手 就深化FPGA解决方案上达成合作
互联网医疗要想兼具流量和口碑 把服务体系做好才是关键
分析4家LED企业的2020年前三季度业绩
采用手写辨识芯片的汉字手写输入技术
引起18650锂电池爆炸的三个原因
unc0ver 6.0:可支持iOS14.5全设备越狱
有限元软件的准确性的验证
回顾2018十大科技发展过程中的不尽人意
微型工控机干啥用的
电子产品热设计的详细说明
HTML5在浏览器之外的未来是什么样子?
导热相变化导热性能好,不易损坏且方便施工
苹果新款macbook pro测评搭载Vega20处理器性能最高跑分超七万
混联电路的简易整理方法详解