本文概念部分粘贴自韦东山老师同步与互斥。
韦东山老师《FreeRTOS入门与工程实践(基于DshanMCU-103)》书籍获取
同步&互斥概念
一句话理解同步与互斥:我等你用完厕所,我再用厕所。
什么叫同步?就是:哎哎哎,我正在用厕所,你等会。
什么叫互斥?就是:哎哎哎,我正在用厕所,你不能进来。
同一时间只能有一个人使用的资源,被称为临界资源。
实现互斥操作的局限性方法
全局变量or静态变量 局限性
在裸机程序,可以使用一个全局变量或静态变量实现互斥操作,比如要互斥地使用
LCD,可以使用如下代码:
int LCD_PrintString(int x, int y, char str)
{static int bCanUse = 1;if (bCanUse){bCanUse = 0;/ 使用LCD */bCanUse = 1;return 0;}return -1;}
这个代码在裸机程序中运行没有问题,但在FreeRTOS中运行可能会有问题。
在裸机程序中,只有一个任务在运行,所以当你设置 bCanUse 变量时,没有其他任务会改变它的值。但在FreeRTOS中,有多个任务可能会并发运行,这会导致并发访问和修改 bCanUse 变量,造成竞态条件(Race Condition)。
使用中断 局限性
使用全局变量or静态变量的方法不能保证万无一失的原因在于:在判断过程中,被打断了。如果能保证这个过程不被打断,就可以了:通过关闭中断来实现。
在if判断前,使用disable_irq()关闭中断,判断结束后再使用enable_irq()打开中断。
但这样做也是有缺陷的,如图:
FreeRTOS的解决方法:正确 & 高效
互斥 -----实现—> 通信的正确性
阻塞唤醒 -----实现—> 提高效率
能实现同步、互斥的内核方法有:
- 任务通知(task notification)
- 队列(queue)
- 事件组(event group)
- 信号量(semaphoe)
- 互斥量(mutex)
它们都有类似的操作方法:获取/释放、阻塞/唤醒、超时。
方法的具体对比: