FreeRTOS信号量

FreeRTOS信号量

信号量是基于队列实现的一种解决任务间同步问题(有序访问)的机制,可以实现对共享资源的有序访问,包括二值信号量、计数型信号量和互斥信号量等。

二值信号量

实际上就是一个队列长度为 1 的队列,通常用于互斥访问或任务同步,但是会导致优先级翻转问题。

优先级翻转问题:当一个高优先级任务因获取一个被低优先级任务获取而处于没有资源状态的二值信号量时,这个高优先级的任务将被阻塞,直到低优先级的任务释放二值信号量,而在这之前,如果有一个优先级介于这个高优先级任务和低优先级任务之间的任务就绪,那么这个中等优先级的任务就会抢占低优先级任务的运行。

创建

xSemaphoreCreateBinary() 使用动态方式创建二值信号量

xSemaphoreCreateBinaryStatic() 使用静态方式创建二值信号量

获取

xSemaphoreTake() 获取信号量
如果信号量处于没有资源的状态,那么此函数可以选择将任务进行阻塞,如果成功获取了信号量,那信号量的资源数将会减 1。

xSemaphoreTakeFromISR(). 在中断中获取信号量
只能用于获取二值信号量和计数型信号量,而不能用于获取互斥信号量。

释放

xSemaphoreGive() 释放信号量
如果信号量处于资源满的状态,那么此函数可续选择将任务进行阻塞,如果成功释放了信号量,那信号量的资源数将会加 1

xSemaphoreGiveFromISR() 在中断中释放信号量

删除

vSemaphoreDelete() 删除信号量

计数型信号量

计数型信号量相当于队列长度大于0 的队列,因此计数型信号量能够容纳多个资源。包含两个场景:

事件计数: 计数型信号量的资源数一般在创建时设置为 0。每次事件发生后,在事件处理函数中释放计数型信号量(计数型信号量的资源数加 1),其他等待事件发生的任务获取计数型信号量(计数型信号量的资源数减 1),这么一来等待事件发生的任务就可以在成功获取到计数型信号量之后执行相应的操作。

资源管理: 计数型信号量的资源数一般在创建时设置为受其管理的共享资源的最大可用数量。一个任务想要访问共享资源,就必须先获取这个共享资源的计数型信号量,之后在成功获取了计数型信号量之后,才可以对这个共享资源进行访问操作,在使用完共享资源后也要释放这个共享资源的计数型信号量。

计数型信号量除了创建函数之外,其余的获取、释放等信号量操作函
数,都与二值信号量相同

创建

xSemaphoreCreateCounting() 使用动态方式创建计数型信号量

xSemaphoreCreateCountingStatic() 使用静态方式创建计数型信号量

获取

xSemaphoreTake() 获取信号量
如果信号量处于没有资源的状态,那么此函数可以选择将任务进行阻塞,如果成功获取了信号量,那信号量的资源数将会减 1。

xSemaphoreTakeFromISR(). 在中断中获取信号量
只能用于获取二值信号量和计数型信号量,而不能用于获取互斥信号量。

释放

xSemaphoreGive() 释放信号量
如果信号量处于资源满的状态,那么此函数可续选择将任务进行阻塞,如果成功释放了信号量,那信号量的资源数将会加 1

xSemaphoreGiveFromISR() 在中断中释放信号量

删除

vSemaphoreDelete() 删除信号量

互斥信号量

互斥信号量其实就是一个拥有优先级继承的二值信号量,适合用于需要互斥访问的应用中。在互斥访问中互斥信号量相当于一把钥匙,当任务想要访问共享资源的时候就必须先获得这把钥匙,当访问完共享资源以后就必须归还这把钥匙,这样其他的任务就可以拿着这把钥匙去访问资源。

优先级继承: 当一个互斥信号量正在被一个低优先级的任务持有时,如果此时有个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,这个过程就是优先级继承。优先级继承尽可能的减少了高优先级任务处于阻塞态的时间,并且将“优先级翻转”的影响降到最低。

互斥信号量不能用于中断服务函数中

  1. 互斥信号量有任务优先级继承的机制,但是中断不是任务,没有任务优先级,所以互斥信号量只能用与任务中,不能用于中断服务函数。
  2. 中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。

互斥信号量除了创建函数之外,其余的获取、释放等信号量操作函数,都与二值信号量相同

创建

xSemaphoreCreateMutex() 使用动态方式创建互斥信号量
xSemaphoreCreateMutexStatic() 使用静态方式创建互斥信号量

获取

xSemaphoreTake() 获取信号量

释放

xSemaphoreGive() 释放信号量

删除

vSemaphoreDelete() 删除信号量

内容参考:正点原子《FreeRTOS开发指南》

FreeRTOS 信号量是一种同步机制,用于在任务之间共享资源。信号量是一个计数器,用于记录可用资源的数量。当一个任务需要使用共享资源时,它会尝试获取信号量。如果信号量计数器的值为正,则任务可以获取该信号量,并将计数器减一。如果信号量的计数器值为零,则任务将进入等待状态,直到有其他任务释放信号量FreeRTOS 中的信号量有两种类型:二进制信号量和计数信号量。 1. 二进制信号量:二进制信号量只有两种状态:可用和不可用。当计数器值为 0 时,信号量不可用;当计数器值为 1 时,信号量可用。 2. 计数信号量:计数信号量允许计数器的值大于 1。当计数器值为 0 时,信号量不可用;当计数器值大于 0 时,信号量可用。 使用 FreeRTOS 信号量需要调用以下函数: 1. `xSemaphoreCreateBinary()`: 创建二进制信号量。 2. `xSemaphoreCreateCounting()`: 创建计数信号量。 3. `xSemaphoreGive()`: 释放信号量。 4. `xSemaphoreTake()`: 获取信号量。 在使用信号量时,需要注意以下几点: 1. 释放信号量的任务必须先获取该信号量。 2. 在获取信号量时,可以设置超时时间,避免任务一直等待。 3. 在使用计数信号量时,需要注意计数器的上限,避免产生资源浪费或死锁的情况。 4. 在使用二进制信号量时,需要注意任务的优先级,避免优先级反转导致的问题。 总之,FreeRTOS 信号量是一种非常实用的同步机制,可以在多任务系统中解决资源共享的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liu_zhaoda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值