STM32 FreeRTOS (四) 信号量

一、简介信号量:

概述

信号量是操作系统中重要的一部分,信号量一般用来进行资源管理和任务同步,FreeRTOS中信号量又分为二值信号量、计数型信号量、互斥信号量和递归互斥信号量。不同的信号量其应用场景不同,但有些应用场景是可以互换着使用的。

信号量的特性

信号量这个名字很恰当:

  • 信号:起通知作用

  • 量:还可以用来表示资源的数量

  1. 当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)

  1. 当"量"只有0、1两个取值时,它就是"二进制信号量"(Binary Semaphores)

支持的动作:"give"给出资源,计数值加1;"take"获得资源,计数值减1

计数型信号量的典型场景是:

  1. 计数:事件产生时"give"信号量,让计数值加1;处理事件时要先"take"信号量,就是获得信号量,让计数值减1。

  1. 资源管理:要想访问资源需要先"take"信号量,让计数值减1;用完资源后"give"信号量,让计数值加1。

信号量的"give"、"take"双方并不需要相同,可以用于生产者-消费者场合:

生产者为任务A、B,消费者为任务C、D

一开始信号量的计数值为0,如果任务C、D想获得信号量,会有两种结果:

  • 阻塞:买不到东西咱就等等吧,可以定个闹钟(超时时间)

  • 即刻返回失败:不等

任务A、B可以生产资源,就是让信号量的计数值增加1,并且把等待这个资源的顾客唤醒

唤醒谁?谁优先级高就唤醒谁,如果大家优先级一样就唤醒等待时间最长的人

信号量跟队列的对比

二进制信号量跟计数型的唯一差别,就是计数值的最大值被限定为1。

差异列表如下:

队列

信号量

可以容纳多个数据,

创建队列时有2部分内存: 队列结构体、存储数据的空间

只有计数值,无法容纳其他数据。

创建信号量时,只需要分配信号量结构体

生产者:没有空间存入数据时可以阻塞

生产者:用于不阻塞,计数值已经达到最大时返回失败

消费者:没有数据时可以阻塞

消费者:没有资源时可以阻塞

两种信号量的对比

信号量的计数值都有限制:限定了最大值。如果最大值被限定为1,那么它就是二进制信号量;如果最大值不是1,它就是计数型信号量。

差别列表如下:

二进制信号量

技术型信号量

被创建时初始值为0

被创建时初始值可以设定

其他操作是一样的

其他操作是一样的

运作机制

二值信号量:

计数信号量:

二值信号量使用案例

在以前,使用DTU模块的时候都是创建一个任务,在while中通过一直循环查询4G模块是否有发送消息过来,当有数据过来的时候再进行处理,这样的方式浪费CPU的资源。最理想的方法就是当没有网络数据的时候网络任务就进入阻塞态,把 CPU 让给其他的任务,当有数据的时候网络任务才去执行。使用了二值信号量,在中断服务函数只需要释放信号量,而在网络处理函数中就一直请求二值信号量,当请求到了,就可以去处理。假如一个中断只通知一个任务的话,可以使用任务通知功能来替代二值信号量,而且使用任务通知的话速度更快,代码量更少。

运行示例图:

二、工程创建:

1.配置RCC时钟

2.配置SYS,将Timebase Source修改为除滴答定时器外的其他定时器。

3.开启FreeRTOS,v1与v2版本不同,一般选用v1即可

4.创建二值信号量Binary Semaphore

  • Semaphore Name: 信号量名称

  • Allocation: 分配方式 Dynamic 动态内存创建

  • Conrol Block Name: 控制块名称

如果想要创建计数信号量Counting Semaphore,必须在 Config parameters 中进行使能。

  • Semaphore Name: 信号量名称

  • Count: 计数信号量的最大值

  • Allocation: 分配方式:Dynamic 动态内存创建

  • Conrol Block Name: 控制块名称

5.创建任务Task

我们创建两个任务,一个信号量接收任务,一个信号量发送任务。

6.GPIO设置

7.UART串口打印

8.生成代码设置

三、相关API说明

库函数:

二值信号量的创建 :xSemaphoreCreateBinary()

函数原型:

函数功能:通过此函数创建二值信号量,信号量所需的RAM是由FreeRTOS动态分配的。此函数创建好的二值信号量默认是空的,也就是说使用xSemaphoreTake()是获取不到的

参数:xSemaphore:保存创建成功的二值信号量句柄。

返回值:

  1. NULL: 二值信号量创建失败。

  1. 其他值: 创建成功的二值信号量的句柄。

创建以一个计数信号量:xSemaphoreCreateCounting()

函数原型:

函数功能:此函数用于创建一个计数型信号量,所需要的内存通过动态内存管理方法分配,真正完成信号量创建的是函数xQueueCreateCountingSemaphore()

参数:

  1. uxMaxCount: 计数信号量最大计数值,当信号量值等于此值的时候释放信号量就会失败。

  1. uxInitialCount: 计数信号量初始值

返回值:

  1. NULL: 计数型信号量创建失败。

  1. 其他值: 计数型信号量创建成功,返回计数型信号量句柄。

信号量的释放 :

1.任务中释放xSemaphoreGive()

函数功能:此函数用于释放二值信号量、计数型信号量或互斥信号量,此函数是一个宏,真正释放信号量的过程是由函数 xQueueGenericSend()来完成的。

参数:xSemaphore:要释放的信号量句柄。

返回值:

  1. pdPASS: 释放信号量成功。

  1. errQUEUE_FULL: 释放信号量失败

2.中断中释放:xSemaphoreGiveFromISR()

函数功能:此函数用于在中断中释放信号量,此函数只能用来释放二值信号量和计数型信号量,绝对不能用来在中断服务函数中释放互斥信号量!此函数是一个宏,真正执行的是函数xQueueGiveFromISR()。

参数:

  1. xSemaphore: 要释放的信号量句柄。

  1. pxHigherPriorityTaskWoken: 标记退出此函数以后是否进行任务切换,这个变量的值由这三个函数来设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。

返回值:

  1. pdPASS: 释放信号量成功。

  1. errQUEUE_FULL: 释放信号量失败

获取信号量
同释放信号量的 API 函数一样,不管是二值信号量、计数型信号量还是互斥信号量,它们都是使用如下这两个函数。
1.任务中获取xSemaphoreTake()

函数功能:此函数用于获取二值信号量、计数型信号量或互斥信号量,此函数是一个宏,真正获取信号量的过程是由函数 xQueueGenericReceive ()来完成的。

参数:

  1. xSemaphore:要获取的信号量句柄。

  1. xBlockTime: 阻塞时间。

返回值:

  • pdTRUE: 获取信号量成功。

  • pdFALSE: 超时,获取信号量失败。

2.中断中获取:xSemaphoreTakeFromISR ()

函数功能:此函数用于在中断服务函数中获取信号量,此函数用于获取二值信号量和计数型信号量,绝 对 不 能 使 用 此 函 数 来 获 取 互 斥 信 号 量 ! 此 函 数 是 一 个 宏 , 真 正 执 行 的 是 函 数xQueueReceiveFromISR ()。

参数:

  1. xSemaphore: 要获取的信号量句柄。

  1. pxHigherPriorityTaskWoken: 标记退出此函数以后是否进行任务切换,这个变量的值由这三个函数来设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。

返回值:

  1. pdPASS: 获取信号量成功。

  1. errQUEUE_FULL: 获取信号量失败

备注:

在中断中获取信号量真正使用的是函数 xQueueReceiveFromISR (),这个函数就是中断级出队函数!当队列不为空的时候就拷贝队列中的数据(用于信号量的时候不需要这一步),然后将队列结构体中的成员变量 uxMessagesWaiting 减一,如果有任务因为入队而阻塞的话就解除阻塞态,当解除阻塞的任务拥有更高优先级的话就将参数 pxHigherPriorityTaskWoken 设置为pdTRUE,最后返回 pdPASS 表示出队成功。如果队列为空的话就直接返回 pdFAIL 表示出队失败!

删除信号量:vSemaphoreDelete()

函数功能:用于删除一个信号量,包括二值信号量,计数信号量,互斥量和递归互斥量。如果有任务阻塞在该信号量上,那么不要删除该信号量。无返回值。

参数:xSemaphore:要删除的信号量句柄。

返回值:

  1. pdPASS: 释放信号量成功。

  1. errQUEUE_FULL: 释放信号量失败

hal库:

创建二值信号量:osSemaphoreCreate

  • 函数描述:创建一个二值量、并返回一个ID

  • 参数:

  1. semaphore_def: 引用由osSemaphoreDef定义的信号量

  1. count: 信号量数量

  • 返回值:成功返回定时器ID,失败返回0

删除信号量:osSemaphoreDelete

  • 函数描述:用于删除一个信号量,包括二值信号量,计数信号量,互斥量和递归互斥量。如果有任务阻塞在该信号量上,那么不要删除该信号量。

  • 参数:semaphore_id: 信号量ID

  • 返回值:错误码

释放信号量:osSemaphoreRelease

  • 函数描述:用于释放信号量的宏。释放的信号量对象必须是已经被创建的,可以用于二值信号量、计数信号量、互斥量的释放,但不能释放由函数 xSemaphoreCreateRecursiveMutex() 创建的递归互斥量。可用在中断服务程序中。

  • 参数:semaphore_id: 信号量ID

  • 返回值:错误

获取信号量:osSemaphoreWait

  • 函数描述:用于获取信号量,不带中断保护。获取的信号量对象可以是二值信号量、计数信号量和互斥量,但是递归互斥量并不能使用这个 API 函数获取。可用在中断服务程序中。

  • 参数:

  1. semaphore_id: 信号量ID

  1. millisec:等待信号量可用的最大超时时间,单位为 tick(即系统节拍周期)。如果宏 INCLUDE_vTaskSuspend 定义为 1 且形参 xTicksToWait 设置为 portMAX_DELAY ,则任务将一直阻塞在该信号量上(即没有超时时间)

  • 返回值:错误

四、实验示例

二值信号量:

这里我创建了两个任务,释放信号量。一个接收信号量。

SendTask:

ReceiveTask:

计数信号量:

SendTask:

ReceiveTask:

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中文的参考手册 内容 Contents5..................................................................................................................................................... 列表 Figures8............................................................................................................................................... 代码清单 Listings9....................................................................................................................................... Tables15 名单.............................................................................................................................................. 列表 Notation15........................................................................................................................................... 章节 1 关于这............................................................................................................................. Manual16 1.1Scope17............................................................................................................................................. 章节 2Task 和调度........................................................................................................................... API20 2.1 portSWITCH_TO_USER_MODE() 21.................................................................................. 2.2 vTaskAllocateMPURegions() 22........................................................................................... 2.3 xTaskAbortDelay() 25............................................................................................................. 2.4 xTaskCallApplicationTaskHook() 27.................................................................................... 2.5 xTaskCheckForTimeOut() 30................................................................................................ 2.6 xTaskCreate() 32..................................................................................................................... 2.7 xTaskCreateStatic() 37........................................................................................................... 2.8 xTaskCreateRestricted() 41................................................................................................... 2.9 vTaskDelay() 46....................................................................................................................... 2.10 vTaskDelayUntil() 48............................................................................................................... 2.11 vTaskDelete() 51..................................................................................................................... 2.12 taskDISABLE_INTERRUPTS() 53........................................................................................ 2.13 taskENABLE_INTERRUPTS() 55......................................................................................... 2.14 taskENTER_CRITICAL() 56.................................................................................................. 2.15 taskENTER_CRITICAL_FROM_ISR() 59........................................................................... 2.16 taskEXIT_CRITICAL() 61....................................................................................................... 2.1 taskEXIT_CRITICAL_FROM_ISR() 63................................................................................ 2.2 xTaskGetApplicationTaskTag() 65....................................................................................... 2.3 xTaskGetCurrentTaskHandle() 67........................................................................................ 2.4 xTaskGetIdleTaskHandle() 68............................................................................................... 2.1 xTaskGetHandle() 69.............................................................................................................. 2.2 uxTaskGetNumberOfTasks() 71........................................................................................... 2.3 vTaskGetRunTimeStats() 72................................................................................................. 2.4 xTaskGetSchedulerState() 76...............................................................................................六 2.5 uxTaskGetStackHighWaterMark() 77.................................................................................. 2.6 eTaskGetState() 79................................................................................................................. 2.7 uxTaskGetSystemState() 81.................................................................................................. 2.8 vTaskGetTaskInfo() 85........................................................................................................... 2.9 pvTaskGetThreadLocalStoragePointer() 87.......................................................................7 2.10 pcTaskGetName() 89.............................................................................................................. 2.11 xTaskGetTickCount() 90........................................................................................................ 2.12 xTaskGetTickCountFromISR() 92........................................................................................ 2.13 vTaskList() 94........................................................................................................................... 2.14 xTaskNotify() 97....................................................................................................................... 2.15 xTaskNotifyAndQuery() 100.................................................................................................. 2.16 xTaskNotifyAndQueryFromISR() 104.................................................................................. 2.17 xTaskNotifyFromISR() 108.................................................................................................... 2.18 xTaskNotifyGive() 113............................................................................................................ 2.19 vTaskNotifyGiveFromISR() 116............................................................................................ 2.20 xTaskNotifyStateClear() 119.................................................................................................. 2.21 ulTask​ ​ NotifyTake() 121.................................................................................................. 2.22 xTaskNotifyWait() 124............................................................................................................ 2.23 uxTaskPriorityGet() 127.......................................................................................................... 2.24 vTaskPrioritySet() 129............................................................................................................ 2.25 vTaskResume() 131................................................................................................................ 2.26 xTaskResumeAll() 133........................................................................................................... 2.27 xTaskResumeFromISR() 136................................................................................................ 2.28 vTaskSetApplicationTaskTag() 139...................................................................................... 2.29 vTaskSetThreadLocalStoragePointer() 141........................................................................ 2.30 vTaskSetTimeOutState() 143................................................................................................ 2.31 vTaskStartScheduler() 145.................................................................................................... 2.32 vTaskStepTick() 147............................................................................................................... 2.33 vTaskSuspend() 149............................................................................................................... 2.34 vTaskSuspendAll() 151.......................................................................................................... 2.35 taskYIELD() 153...................................................................................................................... 章节 3Queue.................................................................................................................................. API155 3.1 vQueueAddToRegistry() 156................................................................................................. 3.2 xQueueAddToSet() 158.......................................................................................................... 3.3 xQueueCreate() 160............................................................................................................... 3.4 xQueueCreateSet() 162......................................................................................................... 3.5 xQueueCreateStatic() 166..................................................................................................... 3.6 vQueueDelete() 168................................................................................................................ 3.7 pcQueueGetName() 170........................................................................................................ 3.8 xQueueIsQueueEmptyFromISR() 171................................................................................. 3.9 xQueueIsQueueFullFromISR() 172...................................................................................... 3.10 uxQueueMessagesWaiting() 173.......................................................................................... 3.11 uxQueueMessagesWaitingFromISR() 174..........................................................................六 3.12 xQueueOverwrite() 176.......................................................................................................... 3.13 xQueueOverwriteFromISR() 178.......................................................................................... 3.14 xQueuePeek() 180.................................................................................................................. 3.15 xQueuePeekFromISR() 183.................................................................................................. 3.16 xQueueReceive() 184............................................................................................................. 3.17 xQueueReceiveFromISR() 187............................................................................................. 3.18 xQueueRemoveFromSet() 190............................................................................................. 3.19 xQueueReset() 192................................................................................................................. 3.20 xQueueSelectFromSet() 193................................................................................................. 3.21 xQueueSelectFromSetFromISR() 195................................................................................. 3.22 xQueueSend() , xQueueSendToFront() , xQueueSendToBack() 197............... 3.23 xQueueSendFromISR() , xQueueSendToBackFromISR() , xQueueSendToFrontFromISR() ............................................................200 3.24 uxQueueSpacesAvailable() 204............................................................................................ 章节 4Semaphore......................................................................................................................... API206 4.1 vSemaphoreCreateBinary() 207........................................................................................... 4.2 xSemaphoreCreateBinary() 210........................................................................................... 4.3 xSemaphoreCreateBinaryStatic() 213................................................................................. 4.4 xSemaphoreCreateCounting() 216....................................................................................... 4.5 xSemaphoreCreateCountingStatic() 219............................................................................. 4.6 xSemaphoreCreateMutex() 222............................................................................................ 4.7 xSemaphoreCreateMutexStatic() 224.................................................................................. 4.8 xSemaphoreCreateRecursiveMutex() 226.......................................................................... 4.9 xSemaphoreCreateRecursiveMutexStatic() 229................................................................ 4.10 vSemaphoreDelete() 231....................................................................................................... 4.11 uxSemaphoreGetCount() 232............................................................................................... 4.12 xSemaphoreGetMutexHolder() 233...................................................................................... 4.13 xSemaphoreGive() 234.......................................................................................................... 4.14 xSemaphoreGiveFromISR() 236.......................................................................................... 4.15 xSemaphoreGiveRecursive() 239......................................................................................... 4.16 xSemaphoreTake() 242.......................................................................................................... 4.17 xSemaphoreTakeFromISR() 245.......................................................................................... 4.18 xSemaphoreTakeRecursive() 247........................................................................................ 章节 5Software 定时器................................................................................................................. API251 5.1 xTimerChangePeriod() 252.................................................................................................... 5.2 xTimerChangePeriodFromISR() 255.................................................................................... 5.3 xTimerCreate() 257................................................................................................................. 5.4 xTimerCreateStatic() 261.......................................................................................................9 5.5 xTimerDelete() 265.................................................................................................................. 5.1 xTimerGetExpiryTime() ....................................................................................................267 5.1 pcTimerGetName() 269.......................................................................................................... 5.2 xTimerGetPeriod() 270........................................................................................................... 5.3 xTimerGetTimerDaemonTaskHandle() 271........................................................................ 5.4 pvTimerGetTimerID() 272...................................................................................................... 5.5 xTimerIsTimerActive() 274..................................................................................................... 5.6 xTimerPendFunctionCall() 276.............................................................................................. 5.7 xTimerPendFunctionCallFromISR() 278..............................................................................8 5.8 xTimerReset() 281................................................................................................................... 5.9 xTimerResetFromISR() 284................................................................................................... 5.10 vTimerSetTimerID() 286......................................................................................................... 5.11 xTimerStart() 288..................................................................................................................... 5.12 xTimerStartFromISR() 290..................................................................................................... 5.13 xTimerStop() 292..................................................................................................................... 5.14 xTimerStopFromISR() 294..................................................................................................... 章节 6Event 组............................................................................................................................... API296 6.1 xEventGroupClearBits() 297.................................................................................................. 6.2 xEventGroupClearBitsFromISR() 299.................................................................................. 6.3 xEventGroupCreate() 302...................................................................................................... 6.4 xEventGroupCreateStatic() 304............................................................................................ 6.1 vEventGroupDelete() 306...................................................................................................... 6.2 xEventGroupGetBits() 307..................................................................................................... 6.1 xEventGroupGetBitsFromISR() 308..................................................................................... 6.2 xEventGroupSetBits() 309..................................................................................................... 6.3 xEventGroupSetBitsFromISR() 311..................................................................................... 6.1 xEventGroupSync() 314......................................................................................................... 6.2 xEventGroupWaitBits() 318................................................................................................... 章节 7Kernel................................................................................................................. Configuration321 7.1 FreeRTOSConfig.h322............................................................................................................... 7.2 常量开始“INCLUDE_”...........................................................................................................323 7.3 常量开始“配置”.......................................................................................................................327 附录 1: 数据类型和编码样式.................................................................................................. Guide347

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值