一、信号量的基本概念
FreeRtos信号量包括二值信号量、计数型信号量、互斥信号量和递归互斥信号量。 信号量用于实现任务间的同步或临界资源的互斥访问《相当于一个上锁机制,代码只有获得了这个锁的钥匙才能够执行。信号量类似于我们在裸机编写中断服务函数中给予标志位赋值的操作,然后根据标志位所对应的函数让其执行。当某个任务需要获得对应的指令才能开始执行时,因为主程序不可能一直等待对应指令的产生而不去执行其它的任务,这时信号量便可保证其它任务能够正常运行的同时也能兼顾到指令一旦发出对应程序能够立马执行。在使用Rtos系统时我们可以借助信号量来完成这个操作,当中断发生的时候就释放信号量,中断服务函数不作任何处理,当任务获取到信号量的时候,就会开始完成对相应任务的处理。这样做的好处是中断执行时间非常短且更节省内存。信号量的使用不仅使用与任务与中断之间的同步,也可以同时实现任务与任务之间的同步。
1.二值信号量
二值信号量(Binary Semaphore)是一种特殊的信号量,其值只能为0或1,0代表获取,1代表释放,因此也被称为互斥二进制信号量(尽管它与传统的互斥锁或互斥量在细节上有所不同)。二值信号量在操作系统、嵌入式系统以及多任务环境中被广泛应用,主要用于任务同步、中断同步以及控制对共享资源的访问。任务同步:信号量在刚被创建时置为空,任务一未获取到信号量而处于阻塞状态,当任务二在某种条件成立下而开始执行并释放信号量,此时任务一获取到信号量由阻塞态阻塞态转为就绪态。如果任务一的优先级是最高的,那么任务会立马执行,从而达到两个任务间的同步。同样的,在中断 服务函数中释放信号量,任务 1 也会得到信号量,从而达到任务与中断间的同步。在FreeRtos当中可以将二值信号量看作一个消息队列,无需关心消息的内容,只需查看队列内是否有消息即可。
二.计数信号量
计数信号量类似于公共停车场,该停车场有50个车位可以供车辆停车,停车场每停放一辆汽车,停车场便减少一个车位,直到停满50辆汽车,该停车场便无法容纳更多车辆。FreeRtos中的计数信号量亦是如此,一个个信号量视为一辆辆汽车,当任务执行时会取走对应的信号量,车辆驶出停车场时,原本的计数值对应减一,停车场的停车位就空出一个。当计数值为50代表着可容纳50个信号量,0个则代表着无位置可容纳更多的信号量,也就代表着系统没有更多的资源给任务去使用,停车场没有更多停车位给其他车辆停放。
三.互斥信号量
互斥信号量是特殊的二值信号量,其特有的优先级继承制机制从而使它更适用于简单的互锁,也就是保护临界资源。(临界资源是指任何时刻都只允许一个任务进行访问),当任务需要访问临界资源时,先获取互斥信号量,使其为空,这样可以使其它任务要使用临界资源时无法获取到信号量而进入阻塞,从而保证了临界资源的单一任务访问。当任务在访问临界资源时,就会给临界资源建立一个标志位,当其它任务想要使用临界资源时会先查询这个标志位,若该标志位不为空则代表临界资源正在被占用,其它任务则进入阻塞态,这样使临界资源得到有效的保护。
4.递归信号量
递归信号量,见文知义,递归嘛,就是可以重复获取调用的,本来按照信号量的特性, 每获取一次可用信号量个数就会减少一个,但是递归则不然,对于已经获取递归互斥量的任务可以重复获取该递归互斥量,该任务拥有递归信号量的所有权。任务成功获取几次递 归互斥量,就要返还几次,在此之前递归互斥量都处于无效状态,其他任务无法获取,只 有持有递归信号量的任务才能获取与释放。
二、二值信号量的运作机制
当任务获取想要信号量时,若获取的信号量无效,则说明对应的任务或中断未释放信号量,此时获取信号的任务就处于阻塞态,若对应的任务或中断释放信号量,则该任务获取到信号量便由阻塞态转为就绪态,若该任务的优先级最高则开始执行。
图1———信号量无效
图2———信号量有效
三、计数值信号量运作机制
计数信号量可以运用于资源管理,允许多个任务获取信号量来访问共享资源,但会限制最大任务访问数目。当任务访问的数目达到最大值,则会阻塞其它任务通过获取信号量来访问共享资源,直到正在访问资源的任务释放信号量结束对共享资源的访问,此时其它的任务才能通过获取信号量来访问共享资源。