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

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

3天内不再提示

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

汽车电子技术 来源:嵌入式之入坑笔记 作者:嵌入式之入坑笔记 2023-02-10 11:04 次阅读

操作系统系统中,信号量通常用于控制对共享资源的访问和任务之间进行同步,信号量在操作系统中是很常用的,也是学习freeRTOS操作系统必须要掌握的。

freeRTOS中最常用到的信号量有:二值信号量、计数信号量、互斥信号量。

有关这几个信号量分别如下:

1、二值信号量

1.1、二值信号量

二值信号量是指所创建的信号量只有两个值(0 和 1),通常用于互斥访问或者同步。

二值信号量在某处被占有使用之后,其他地方想要申请这个二值信号量是无法成功申请的,只有当这个被占有的二值信号量被使用完毕并释放之后,才能被再次申请占有使用!

总而言之,二值信号量被使用之后会变为无效状态,需要被重新释放才能进入有效状态。

在freeRTOS中,二值信号量的创建和使用的API管理函数分别如下:

1.2、创建二值信号量

函数原型:SemaphoreHandle_t xSemaphoreCreateBinary(void)

函数描述:

函数** xSemaphoreCreateBinary** 用于创建二值信号量。

返回值: 如果创建成功会返回二值信号量的句柄,创建失败会返回 NULL。

1.3、等待二值信号量

在freeRTOS中,信号量的获取是进行了区分的,在任务或者函数中获取与在中断中是不一样的,freeRTOS中给出了不同API函数。

1)在任务代码中等待信号量

函数原型:xSemaphoreTake( SemaphoreHandle_t xSemaphore,  /* 信号量句柄 */           TickType_t xTicksToWait );     /* 等待信号量可用的最大等待时间 */

函数描述:

函数 xSemaphoreTake 用于在任务代码中获取信号量。

第 1 个参数是信号量句柄。

第 2 个参数是没有信号量可用时,等待信号量可用的最大等待时间,单位系统时钟节拍。

返回值:如果创建成功会获取信号量返回 pdTRUE,否则返回 pdFALSE。

使用这个函数要注意以下问题:

此函数是用于任务代码中调用的,不可以在中断服务程序中调用此函数,中断服务程序使用的是xSemaphoreTakeFromISR。

2)在中断中等待信号量

xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )

函数描述:

函数xSemaphoreTakeFromISR用于在中断中获取信号量。

第 1 个参数是要获取的信号量的句柄。这是创建信号量时返回的句柄。

第 2 个参数是如果采用信号量导致任务取消阻止,并且未阻止的任务的优先级高于当前运行的任务,则xSemaphoreTakeFromISR()会将pxHigherPriorityTaskWoken设置为pdTRUE。

如果xSemaphoreTakeFromISR()将此值设置为pdTRUE,则应在退出中断之前请求上下文切换。

返回值:如果创建成功会获取信号量返回 pdTRUE,否则返回 pdFALSE。

1.4、释放二值信号量

1)用于在任务代码中释放二值信号量

函数原型:

xSemaphoreGive( SemaphoreHandle_t xSemaphore ); /* 信号量句柄 */

函数描述:释放信号量

函数 xSemaphoreGive 用于在任务代码中释放信号量。

第 1 个参数是信号量句柄。

返回值,如果信号量释放成功返回 pdTRUE,否则返回 pdFALSE,因为信号量的实现是基于消息队列,返回失败的主要原因是消息队列已经满了。

注意:此函数是用于任务代码中调用的,不可以在中断服务程序中调用此函数。

2)用于在中断中释放二值信号量

函数原型:

xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)

函数描述:

函数 xSemaphoreGiveFromISR 用于中断服务程序中释放信号量。

第 1 个参数是信号量句柄。

第2个参数用于保存是否有高优先级任务准备就绪。如果函数执行完毕后,此参数的数值是pdTRUE,说明有高优先级任务要执行,否则没有。

返回值:如果信号量释放成功返回 pdTRUE,否则返回 errQUEUE_FULL。

2、计数信号量

计数信号量是一个相当于长度大于1的队列,用于任务之间的同步和共享资源的保护。

计数信号量与二值信号量的不同在于,二值信号量只能被一个地方申请使用,只有在这个申请使用的地方了释放了才能被其他处申请使用。而计数信号量是可以创建一定数量的信号量的,多个地方可以同时申请使用,直到达到最大的计数信号量的阈值。

计数信号量相关的API函数:

2.1、创建计数信号量

SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,   /* 支持的最大计数值 */               UBaseType_t uxInitialCount);    /* 初始计数值 */

第 1 个参数:设置此计数信号量支持的 最大计数值

第 2 个参数:设置计数信号量的 初始值 。(为0则不起作用)

返回值:如果创建成功会返回消息队列的句柄,创建失败会返回 NULL。

2.2、获取信号量

1)在任务代码中获取信号量

xSemaphoreTake( SemaphoreHandle_t xSemaphore, /* 信号量句柄 */           TickType_t xTicksToWait ); /* 等待信号量可用的最大等待时间 */

函数 xSemaphoreTake 用于在任务代码中获取信号量。

第 1 个参数是信号量句柄。

第 2 个参数是没有信号量可用时,等待信号量可用的最大等待时间,单位系统时钟节拍。

返回值:如果信号量获取成功会返回 pdTRUE,否则返回 pdFALSE。

2)在中断中获取信号量

xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )

函数描述:

函数 **xSemaphoreTakeFromISR **用于在中断中获取信号量。

第 1 个参数是要获取的信号量的句柄。这是创建信号量时返回的句柄。

第 2 个参数是如果采用信号量导致任务取消阻止,并且未阻止的任务的优先级高于当前运行的任务,则xSemaphoreTakeFromISR()会将pxHigherPriorityTaskWoken设置为pdTRUE。如果xSemaphoreTakeFromISR()将此值设置为pdTRUE,则应在退出中断之前请求上下文切换。

返回值,如果创建成功会获取信号量返回 pdTRUE,否则返回 pdFALSE。

2.3、释放信号量

1)在任务代码中释放信号量

xSemaphoreGive( SemaphoreHandle_t xSemaphore ); /* 信号量句柄 */

函数 xSemaphoreGive 用于在任务代码中释放信号量。

第 1 个参数是信号量句柄。

返回值,如果信号量释放成功返回 pdTRUE,否则返回 pdFALSE,因为计数信号量的实现是基于消息队列,返回失败的主要原因是消息队列已经满了。

2)在中断中释放信号量

xSemaphoreGiveFromISR(          SemaphoreHandle_t xSemaphore, /* 信号量句柄 */          signed BaseType_t *pxHigherPriorityTaskWoken /* 高优先级任务是否被唤醒的状态保存 */          )

第 1 个参数是信号量句柄。

第2个参数用于保存是否有高优先级任务准备就绪。如果函数执行完毕后,此参数的数值是pdTRUE,说明有高优先级任务要执行,否则没有。

返回值:如果信号量释放成功返回 pdTRUE,否则返回 errQUEUE_FULL。

3、优先级反转 & 互斥信号量

在实时操作系统中,优先级反转的问题是不容忽视的,程序设计的过程中,也是要充分考虑这个问题的。

那优先级反转到底是什么呢?

优先反转是指:假如一个系统中有高(H)、中(M)、低(L)三个优先级的任务,并有一个二值信号量。在某一个时刻二值信号量被低(L)优先级的任务使用了,并在运行过程中,高优先级任务(H)抢占了低优先级(L)的CPU使用权,但是也想要获取二值信号量被低优先(L)的任务占有着,高优先级任务(H)由此被挂起等待了,中优先级任务(M)因为不需要二值信号量,会抢占低优先级(L)任务的执行而得到运行,而高优先级任务(H)依然只能等到低优先级任务(L)释放二值信号量才能得到执行。

由此造成了高优先级任务得不到及时的执行,而低优先级任务却能比高优先级任务更多的得到执行。

优先级互斥的示意图如下:

图片

解决优先级反转的问题最好的办法是使用互斥信号量。

互斥信号量和二值信号量比较相似,不同之处在于互斥信号量具有优先级继承的特性,如果一个互斥信号量正在被一个低优先级的任务使用,而此时这个高优先级的任务也希望获取这个互斥信号量的话就会被阻塞。

使用互斥信号量时,高优先级的任务会把低优先级的任务的优先级先提高到和自己相同的优先级,保证低优先级的任务能够继续运行至结束这样极大减少了因为高优先级获取不到信号量被阻塞过长时间的问题。

互斥信号量的API函数:

1)创建互斥信号量

函数原型:

SemaphoreHandle_t xSemaphoreCreateMutex(void)

函数描述:

函数 xSemaphoreCreateMutex 用于创建互斥信号量。

返回值:如果创建成功会返回互斥信号量的句柄,失败会返回 NULL。

2)获取互斥信号量

函数原型:

xSemaphoreTake( SemaphoreHandle_t xSemaphore, /* 信号量句柄 */           TickType_t xTicksToWait ); /* 等待信号量可用的最大等待时间 */

函数描述:

函数 xSemaphoreTake 用于在任务代码中获取信号量。

第 1 个参数是信号量句柄。

第 2 个参数是没有信号量可用时,等待信号量可用的最大等待时间,单位系统时钟节拍。

返回值:如果创建成功会获取信号量返回 pdTRUE,否则返回 pdFALSE。

(2)释放互斥信号量

函数原型:

xSemaphoreGive( SemaphoreHandle_t xSemaphore ); /* 信号量句柄 */

函数描述:

函数 xSemaphoreGive 用于在任务代码中释放信号量。

第 1 个参数是信号量句柄。

返回值:如果信号量释放成功返回 pdTRUE,否则返回 pdFALSE,因为信号量的实现是基于消息队列,返回失败的主要原因是消息队列已经满了。

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

    关注

    37

    文章

    6288

    浏览量

    121886
  • FreeRTOS
    +关注

    关注

    12

    文章

    473

    浏览量

    61349
  • 信号量
    +关注

    关注

    0

    文章

    53

    浏览量

    8257
收藏 人收藏

    评论

    相关推荐

    FreeRTOS信号量使用教程

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

    转:freeRTOS信号量学习

    信号量同样是RTOS学习中很重要的一节,信号量可以用在共享资源或者同步任务中,对执行权的控制,谁拥有信号量谁拥有执行权,在freeRTOS信号量
    发表于 08-12 18:29

    转:第21章 FreeRTOS计数信号量

    信号量功能,设置不同的初始值就可以分别实现二值信号量和计数信号量。当然,FreeRTOS使用计数信号量也能够实现同样的效果。实际上
    发表于 09-05 09:36

    转:第22章 FreeRTOS二值信号量

    本章节讲解FreeRTOS任务间的同步和资源共享机制,二值信号量。二值信号量是计数信号量的一种特殊形式,即共享资源为1的情况。(注:本章节开头部分的知识介绍与上一章节计数
    发表于 09-06 10:02

    转:第23章 FreeRTOS互斥信号量

    本章节讲解FreeRTOS重要的资源共享机制---互斥信号量(Mutex,即MutualExclusion的缩写)。注意,建议初学者学习完前两个章节的信号量后再学习本章节的互斥信号量
    发表于 09-06 14:58

    freertos信号量同步的时候多任务运行老是崩溃的原因?

    freertos信号量同步的时候,多任务运行,老是崩溃,各位没遇到过目前移植了,freertos 系统,所以需要用到,线程同步,然后使
    发表于 06-18 09:00

    有关FreeRTOS信号量和计数信号量在使用过程中需要注意的细节

    本文介绍有关FreeRTOS信号量和计数信号量在使用过程中需要注意的细节,以及自己在过程中的分享的一些有关遇到的问题和注意点。
    发表于 08-06 06:26

    如何创建FreeRTOS任务/信号量/串口底层?

    如何创建FreeRTOS任务/信号量/串口底层?
    发表于 12-16 07:39

    信号量是什么?信号量怎么运作

    任务只能等待),常用于协助一组相互竞争的任务来访问临界资源。在多任务系统中,各任 务之间需要同步(一个任务的完成的瞬间另一个任务开始)或互斥实现临界资源的保护,信号量功能可以为用户提供这方面的支持。...
    发表于 01-05 08:09

    FreeRTOS信号量介绍

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

    FreeRTOS信号量 & ESP32实战

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

    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 15:07 938次阅读