提示: 任务通知在某些情况下可以提供一个轻量的选择用以替代二值信号量,详见:任务通知
二值信号量(Binary Semaphores
)通常用来实现互斥、同步。二值信号量与互斥量虽然相似,但是互斥量拥有优先级继承的特性,而二值信号量没有。这使得二值信号量更加合适去实现同步,互斥量更加适合去实现互斥。
信号量可以设置阻塞时间,当任务试图获取一个暂时不可用的信号量的适时候,会进入阻塞态,直到阻塞时间到,或者信号量可用。同样的,多个任务等待同一个信号量,高优先级的任务在信号量有效时优先退出阻塞态。
对于二值信号量,可以想象成一个只能保存一个成员的队列,因此队列只有两种情况:空或者满(0、1)。任务和中断在使用这种队列的时候只关心这个队列是空还是非空,这种机制可以用来实现队列和任务间的同步,比如中断中将队列填满,那么一个在等待这个队列未满的任务,此时会得到执行(假如其优先级最高)。
考虑这样一种情况,假如一个任务在服务一个外设,如果一直去轮询这个外设将浪费CPU时间,同时其他任务也会得不到执行,如果使用二值信号量来做,在这个外设的某个事件没到来的时候,二值信号量为无效,任务出于阻塞态,不占用CPU时间。事件到来时,将二值信号量置为有效,任务将得到同步,然后去处理外设。这种方式是很高效的。任务,处在接收的角色,而中断则是以给予的角色出现。具体的实现可以参考相应API函数。
任务的优先级可以保证外设被及时的服务到,这实际上是实现了一个具有很短延时的”中断机制”,外设中断到来,内核调度相应任务去处理,相比原来直接在中断中处理,会有一个很短的延迟,但是是可接受的。这也意味着,中断需要越短越好,占用的时间越少越好。下图是中断与任务同步的机制:
关于如何使用,可以参考官方例程,在路径FreeRTOS/Demo/Common/Minimal
下。后续在进阶内容中我也会做一些整理,敬请期待^_^.