0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FreeRTOS四种信号量详细介绍

麦辣鸡腿堡 来源:嵌入式Linux系统开发 作者:嵌入式Linux系统开 2023-07-06 17:14 次阅读

1、二值信号

二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承。因此二值信号量更适合用于同步(任务与任务或任务与中断的同步),而互斥信号量适合用于简单的互斥访问。

和队列一样,信号量 API 函数允许设置一个阻塞时间,阻塞时间是当任务获取信号量的时候由于信号量无效从而导致任务进入阻塞态的最大时钟节拍数。如果多个任务同时阻塞在同一个信号量上的话那么优先级最高的哪个任务优先获得信号量,这样当信号量有效的时候高优先级的任务就会解除阻塞状态。

二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的,这不正好就是二值的吗?任务和中断使用这个特殊队列不用在乎队列中存的是什么消息,只需要知道这个队列是满的还是空的。可以利用这个机制来完成任务与中断之间的同步。

在实际应用中通常会使用一个任务来处理 MCU 的某个外设,比如网络应用中,一般最简单的方法就是使用一个任务去轮询的查询 MCU 的 ETH 外设是否有数据,当有数据的时候就处理这个网络数据。这样使用轮询的方式是很浪费CPU 资源的,而且也阻止了其他任务的运行。最理想的方法就是当没有网络数据的时候网络任务就进入阻塞态,把 CPU 让给其他的任务,当有数据的时候网络任务才去执行。现在使用二值信号量就可以实现这样的功能,任务通过获取信号量来判断是否有网络数据,没有的话就进入阻塞态,而网络中断服务函数通过释放信号量来通知任务以太网外设接收到了网络数据,网络任务可以去提取处理了。网络任务只是在一直的获取二值信号量,它不会释放信号量,而中断服务函数是一直在释放信号量,它不会获取信号量。在中断服务函数中发送信号量可以使用函数 xSemaphoreGiveFromISR()。

2、计数型信号量

有些资料中也将计数型信号量叫做数值信号量,二值信号量相当于长度为 1 的队列,那么计数型信号量就是长度大于 1 的队列。同二值信号量一样,用户不需要关心队列中存储了什么数据,只需要关心队列是否为空即可。计数型信号量通常用于如下两个场合:

事件计数

在这个场合中,每次事件发生的时候就在事件处理函数中释放信号量(增加信号量的计数值),其他任务会获取信号量(信号量计数值减一,信号量值就是队列结构体成员变量uxMessagesWaiting)来处理事件。在这种场合中创建的计数型信号量初始计数值为 0。

资源管理

在这个场合中,信号量值代表当前资源的可用数量,比如停车场当前剩余的停车位数量。一个任务要想获得资源的使用权,首先必须获取信号量,信号量获取成功以后信号量值就会减一。当信号量值为 0 的时候说明没有资源了。当一个任务使用完资源以后一定要释放信号量,释放信号量以后信号量值会加一。在这个场合中创建的计数型信号量初始值应该是资源的数量,比如停车场一共有 100 个停车位,那么创建信号量的时候信号量值就应该初始化为 100。

3、互斥信号量

互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中(任务与任务或中断与任务之间的同步)二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一个钥匙,当任务想要使用资源的时候就必须先获得这个钥匙,当使用完资源以后就必须归还这个钥匙,这样其他的任务就可以拿着这个钥匙去使用资源。

互斥信号量使用和二值信号量相同的 API 操作函数,所以互斥信号量也可以设置阻塞时间,不同于二值信号量的是互斥信号量具有优先级继承的特性。当一个互斥信号量正在被一个低优先级的任务使用,而此时有个高优先级的任务也尝试获取这个互斥信号量的话就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,这个过程就是优先级继承。优先级继承尽可能的降低了高优先级任务处于阻塞态的时间,并且将已经出现的“优先级翻转”的影响降到最低。

优先级继承并不能完全的消除优先级翻转,它只是尽可能的降低优先级翻转带来的影响。硬实时应用应该在设计之初就要避免优先级翻转的发生。互斥信号量不能用于中断服务函数中,原因如下:

● 互斥信号量有优先级继承的机制,所以只能用在任务中,不能用于中断服务函数。

● 中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。

4、递归互斥信号量

递归互斥信号量可以看作是一个特殊的互斥信号量,已经获取了互斥信号量的任务就不能再次获取这个互斥信号量,但是递归互斥信号量不同,已经获取了递归互斥信号量的任务可以再次获取这个递归互斥信号量,而且次数不限!一个任务使用函数 xSemaphoreTakeRecursive()成功的获取了多少次递归互斥信号量就得使用函数 xSemaphoreGiveRecursive()释放多少次!比如某个任务成功的获取了 5 次递归信号量,那么这个任务也得同样的释放 5 次递归信号量。

递归互斥信号量也有优先级继承的机制,所以当任务使用完递归互斥信号量以后一定要记得释放。同互斥信号量一样,递归互斥信号量不能用在中断服务函数中。

● 由于优先级继承的存在,就限定了递归互斥信号量只能用在任务中,不能用在中断服务函数中!

● 中断服务函数不能设置阻塞时间。

要使用递归互斥信号量的话宏 configUSE_RECURSIVE_MUTEXES 必须为 1!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5017

    文章

    18501

    浏览量

    293405
  • 信号
    +关注

    关注

    11

    文章

    2687

    浏览量

    75780
  • FreeRTOS
    +关注

    关注

    12

    文章

    474

    浏览量

    61526
收藏 人收藏

    评论

    相关推荐

    FreeRTOS串口中断接收不定长的数据与二值信号量的使用

    FreeRTOS例程,使用串口中断接收不定长的数据,以及二值信号量的使用
    的头像 发表于 09-26 09:02 3610次阅读
    <b class='flag-5'>FreeRTOS</b>串口中断接收不定长的数据与二值<b class='flag-5'>信号量</b>的使用

    FreeRTOS信号量使用教程

    信号量是操作系统中重要的一部分,信号量一般用来进行资源管理和任务同步, FreeRTOS信号量又分为二值信号量、 计数型
    的头像 发表于 12-19 09:22 2664次阅读
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>信号量</b>使用教程

    FreeRTOS信号量的使用与实例

    在嵌入式系统中,任务管理是一个重要的部分,它涉及到任务之间的通信和同步,信号量,队列,互斥锁和事件标志组等概念。本文将以 FreeRTOS 为例,详细讲解这些内容。
    的头像 发表于 12-12 15:25 1087次阅读

    转:freeRTOS信号量学习

    ,在编译的时候静态分配给信号量,前者则是动态分配,关于静态分配和动态分配可以参阅freeRTOS官网详细信息。我们看一下两API创建信号量
    发表于 08-12 18:29

    FreeRTOS信号量介绍

    FreeRTOS信号量 & ESP32实战阅读建议:有一定操作系统基础知识。FreeRTOS信号量1. 二值信号量  二值
    发表于 01-27 07:28

    uCOS信号量源码的详细资料分析

    本文档的主要内容详细介绍的是uCOS信号量源码的详细资料分析。 信号量相关的函数 创建一个信号量
    发表于 06-17 17:38 7次下载
    uCOS<b class='flag-5'>信号量</b>源码的<b class='flag-5'>详细</b>资料分析

    Linux信号量(2):POSIX 信号量

    上一章,讲述了 SYSTEM V 信号量,主要运行于进程之间,本章主要介绍 POSIX 信号量:有名信号量、无名信号量。 POSIX
    的头像 发表于 10-29 17:34 519次阅读

    FreeRTOS信号量 & ESP32实战

    FreeRTOS信号量 & ESP32实战阅读建议:有一定操作系统基础知识。FreeRTOS信号量1. 二值信号量  二值
    发表于 12-03 18:06 1次下载
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>信号量</b> & ESP32实战

    FreeRTOS 队列 信号量 互斥

    文章目录前言Queue 队列semaphore 信号量Mutex 互斥微信公众号前言FreeRTOS STM32CubeMX配置 内存管理 任务管理上节介绍了用STM32CubeMX
    发表于 12-09 09:51 0次下载
    <b class='flag-5'>FreeRTOS</b> 队列 <b class='flag-5'>信号量</b> 互斥<b class='flag-5'>量</b>

    FreeRTOS高级篇6---FreeRTOS信号量分析

    FreeRTOS信号量包括二进制信号量、计数信号量、互斥信号量(以后简称互斥)和递归互斥
    发表于 01-26 17:39 7次下载
    <b class='flag-5'>FreeRTOS</b>高级篇6---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>信号量</b>分析

    FreeRTOS系列第20篇---FreeRTOS信号量API函数

    FreeRTOS信号量包括二进制信号量、计数信号量、互斥信号量(以后简称互斥)和递归互斥
    发表于 01-26 17:44 4次下载
    <b class='flag-5'>FreeRTOS</b>系列第20篇---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>信号量</b>API函数

    在Arduino IDE中使用FreeRTOS信号量

    电子发烧友网站提供《在Arduino IDE中使用FreeRTOS信号量.zip》资料免费下载
    发表于 01-04 10:18 0次下载
    在Arduino IDE中使用<b class='flag-5'>FreeRTOS</b><b class='flag-5'>信号量</b>

    freeRTOS中最常用到的信号量有哪些

    在操作系统系统中,信号量通常用于控制对共享资源的访问和任务之间进行同步,信号量在操作系统中是很常用的,也是学习freeRTOS操作系统必须要掌握的。
    的头像 发表于 02-10 11:04 1353次阅读
    <b class='flag-5'>freeRTOS</b>中最常用到的<b class='flag-5'>信号量</b>有哪些

    FreeRTOS的二值信号量

    FreeRTOS中的信号量是一任务间通信的方式,信号量包括:二值信号量、互斥信号量、计数
    的头像 发表于 02-10 15:07 1082次阅读

    FreeRTOS信号量介绍

    1、信号量用于控制对共享资源的访问 举一个很常见的例子,某个停车场有100个停车位,这 100 个停车位大家都可以用,对于大家来说这 100 个停车位就是共享资源。假设现在这个停车场正常运行,你要把
    的头像 发表于 07-06 17:09 493次阅读