FreeRTOS--信号量

本文详细介绍了FreeRTOS中信号量的概念、计数信号量API的使用(包括创建、释放和获取)以及二进制信号量的应用。重点讨论了如何通过信号量实现任务间的同步和资源管理,包括互斥信号量的区别和使用限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、信号量的概念及其作用

        使用信号量的最初目的是为了给共享资源建立一个标志,该标志表示该共享资源被占用情况

平时使用信号量主要实现以下两个功能:

        1、两个任务之间或者中断函数跟任务之间的同步功能,其实就是共享资源为 1 的时候;

        2、多个共享资源的管理;

针对这两种功能,FreeRTOS分别提供了二进制信号量和计数信号量,二进制信号量可以被认为是长度为 1 的队列那样,计数信号量也可以被认为是长度大于 1 的队列。

二、计数信号量 API 函数

1)函数 xSemaphoreCreateCounting 用于创建计数信号量

使用此函数要在 FreeRTOSConfig.h 文件中使能宏定义:

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

参数:

uxMaxCount  可以达到的最大计数值。 当信号量达到此值时,它不能再被“给定”。
uxInitialCount  创建信号量时分配给信号量的计数值。

返回:

如果已成功创建信号量,则将返回该信号量的句柄 。

2)函数 xSemaphoreGive 用于在任务代码中释放信号量
xSemaphoreGive( SemaphoreHandle_t xSemaphore ); /* 信号量句柄 */

返回值:如果信号量释放成功,则返回 pdTRUE;如果发生错误,则返回 pdFALSE。

3)函数 xSemaphoreGiveFromISR 用于中断服务程序中释放信号量
xSemaphoreGiveFromISR
(
    SemaphoreHandle_t xSemaphore,                /* 信号量句柄 */
    signed BaseType_t *pxHigherPriorityTaskWoken /* 高优先级任务是否被唤醒的状态保存 */
)

pxHigherPriorityTaskWoken:参数的数值是 pdTRUE,说明有高优先级任务要执行, 否则没有

 返回:如果成功给出信号量,则返回 pdTRUE,否则 errQUEUE_FULL。

4)函数 xSemaphoreTake 用于在任务代码中获取信号量
xSemaphoreTake( SemaphoreHandle_t xSemaphore, /* 信号量句柄 */
                TickType_t xTicksToWait );    /* 等待信号量可用的最大等待时间 */

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

三、FreeRTOS 任务间计数信号量的实现

 

运行条件:

 创建 2 个任务 Task1 和 Task2

 创建计数信号量可用资源为 1

运行过程描述如下:

 任务 Task1 运行过程中调用函数 xSemaphoreTake 获取信号量资源, 如果信号量没有被任务 Task2占用, Task1 将直接获取资源。 如果信号量被 Task2 占用, 任务 Task1 将由运行态转到阻塞状态,等待资源可用。一旦获取了资源并使用完毕后会通过函数 xSemaphoreGive 释放掉资源。

 任务 Task2 运行过程中调用函数 xSemaphoreTake 获取信号量资源, 如果信号量没有被任务 Task1占用, Task2 将直接获取资源。 如果信号量被 Task1 占用, 任务 Task2 将由运行态转到阻塞状态,等待资源可用。一旦获取了资源并使用完毕后会通过函数 xSemaphoreGive 释放掉资源。

测试步骤:1.使用xSemaphoreCreateCounting初始化有一个可以资源

                  2.创建两个任务xSemaphoreTake 抢占信号量资源

                  3.通过串口接收指令xSemaphoreGive 释放信号量资源

        4.优先级高的先抢到信号量,使用完后释放,延迟短时间给低优先级任务有机会抢占信号量

四、FreeRTOS 中断方式计数信号量的实现

 运行条件:

 创建一个任务 Task1 和一个串口接收中断

 信号量的初始值为 0,串口中断调用函数 xSemaphoreGiveFromISR 释放信号量, 任务 Task1 调用函数 xSemaphoreTake 获取信号量资源。

运行过程描述如下:

 任务 Task1 运行过程中调用函数 xSemaphoreTake, 由于信号量的初始值是 0,没有信号量资源可用,任务 Task1 由运行态进入到阻塞态。

 Task1 阻塞的情况下,串口接收到数据进入到了串口中断服务程序,在串口中断服务程序中调用函数xSemaphoreGiveFromISR 释放信号量资源,信号量数值加 1, 此时信号量计数值为 1,任务 Task1由阻塞态进入到就绪态,在调度器的作用下由就绪态又进入到运行态, 任务 Task1 获得信号量后,信号量数值减 1, 此时信号量计数值又变成了 0。

 再次循环执行时,任务 Task1 调用函数 xSemaphoreTake 由于没有资源可用再次进入到阻塞态,等待串口释放信号量资源,如此往复循环。

测试步骤:1.使用xSemaphoreCreateCounting初始化有一个可以资源

                  2.创建两个任务xSemaphoreTake 抢占信号量资源

 3.串口接收指令开启定时器,在定时器中断回调函数xSemaphoreGiveFromISR 释放信号量资源

 4.优先级高的先抢到信号量,使用完后释放,延迟短时间给低优先级任务有机会抢占信号量

五、二进制信号量API函数

1)函数 xSemaphoreCreateBinary 用于创建二值信号量

SemaphoreHandle_t xSemaphoreCreateBinary(void);

返回一个可以引用该信号量的句柄

2)信号量的获取以及释放跟上面API一致


--用法与上面基本一致--

六、互斥信号量

1、概念及其作用

        互斥信号量的主要作用是对资源实现互斥访问, 使用二值信号量也可以实现互斥访问的功能,不过互斥信号量与二值信号量有区别。互斥信号量可以防止优先级翻转, 而二值信号量不支持。互斥信号量仅支持用在 FreeRTOS 的任务中,中断函数中不可使用
 

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

SemaphoreHandle_t xSemaphoreCreateMutex( void ) 

 返回值: 如果创建成功会返回互斥信号量的句柄。使用需要配置如下:

函数的释放以及获取API与上述一致,注意中断中不可用xSemaphoreGiveFromISR

 七、测试例程:

https://gitee.com/hutaooooooo/git_keil/tree/master/freetos_xSemaphoreCreate

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值