在 Arduino 中使用 FreeRTOS 的信号量和互斥锁


信号量和互斥锁是 FreeRTOS 中用于实现任务同步的工具/机制。通常,两个任务需要共享资源,或者一个任务需要告诉另一个任务它处于空闲/等待状态。信号量和互斥锁在这里提供帮助。在本文中,我们将了解信号量和互斥锁的概念。

信号量

信号量是任务之间的一种同步机制。更具体地说,它是一种信号机制。处于等待状态的任务可能会收到一个信号量,指示它执行某些工作。一旦任务完成该工作,它将返回信号量。在实践中,这是由整数维护的。信号量有两种类型:二进制信号量和计数信号量。

二进制信号量

这类似于长度为 1 的队列。它只能取 0 和 1 作为整数值。假设有两个任务:任务 A 和任务 B。如果任务 A 需要向任务 B 发送一些周期性通信(例如数据交换),则它使用此二进制信号量进行通信。当数据可用时,它将信号量的值设置为 1(任务 A 在这里“给出”信号量)。持续监视信号量的任务 B 将在值为 1 时读取数据。然后它将队列的值重置为 0(因此,任务 B“获取”信号量),并再次等待数据可用。通过这种方式,实现了任务 A 和任务 B 之间的同步。

计数信号量

在这种情况下,对队列长度没有限制。这用于事件管理。每次发生事件时,事件处理程序都会通过增加计数器值来“给出”信号量。每次任务处理事件时,它都会通过递减计数器来指示它已“获取”信号量。任何给定时间的计数都显示已发生事件数和已处理事件数之间的差。

互斥锁

互斥锁(互斥)是一种锁定机制,可防止共享资源损坏。假设您有一个被多个任务访问的 SD 卡。如果多个任务同时访问它,则有可能损坏 SD 卡中的数据(两者都可能写入相同的内存区域,导致垃圾数据)。

为了避免这种情况,我们使用互斥锁。它就像一个令牌。如果一个任务拥有此令牌,则只有该任务才能访问特定资源。其他任务必须等到该任务释放令牌。如果您有多个需要保护的资源(例如 OLED 屏幕、SD 卡、串口等),您可以为每个资源使用多个令牌。

实际上,互斥锁使用与二进制信号量相同的 API 函数。唯一的区别是互斥锁具有优先级继承。FreeRTOS 文档 将其描述为:

“如果高优先级任务在尝试获取当前由低优先级任务持有的互斥锁(令牌)时阻塞,则持有令牌的任务的优先级将暂时提高到阻塞任务的优先级。此机制旨在确保高优先级任务保持阻塞状态的时间尽可能短,从而最大限度地减少已经发生的“优先级反转”。

为了查看信号量和互斥锁的实际实现,您可以查看 FreeRTOS 库附带的以下示例:Mutex、AnalogRead_DigitalRead、Interrupts。

更新于:2021年5月29日

1K+ 次查看

启动您的职业生涯

通过完成课程获得认证

开始学习
广告