FreeRTOS之信号量
文章目录
- 概述
- 队列和信号量对比
- 信号量函数
- 创建
- 删除
- give/take
概述
- 信号量本质上也是一个队列,只不过不涉及数据传输,只涉及数据个数的加加减减,换句话说就是传递状态。使用信号量效率更高、更节省内存
- 分类
- 计数型信号量(Counting Semaphores):量没有限制
- 二进制信号量(Binary Semaphores):量只有 0、1 两个取值
- 支持的动作:
- "give"给出资源,计数值加 1
- "take"获得资源,计数值减 1
队列和信号量对比
队列 | 信号量 |
---|---|
可以容纳多个数据, 创建队列时有2部分内存:队列结构体、存储数据的空间 | 只有计数值,无法容纳其他数据。 创建信号量时,只需要分配信号量结构体 |
生产者:没有空间存入数据时可以阻塞 | 生产者:不阻塞,计数值已经达到最大时返回失败 |
消费者:没有数据时可以阻塞 | 消费者:没有资源时可以阻塞 |
信号量函数
- 使用信号量时,先创建、然后去添加资源、获得资源。使用句柄来表示一个信号量。
创建
二进制信号量 | 计数型信号量 | |
---|---|---|
动态创建 | xSemaphoreCreateBinary 计数值初始值为 0 | xSemaphoreCreateCounting |
静态创建 | xSemaphoreCreateBinaryStatic | xSemaphoreCreateCountingStatic |
/* 创建一个二进制信号量,返回它的句柄。
* 此函数内部会分配信号量结构体
* 返回值: 返回句柄,非 NULL 表示成功
*/
SemaphoreHandle_t xSemaphoreCreateBinary( void );
/* 创建一个二进制信号量,返回它的句柄。
* 此函数无需动态分配内存,所以需要先有一个 StaticSemaphore_t 结构体,并传入它的
指针
* 返回值: 返回句柄,非 NULL 表示成功
*/
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuf
fer );
/* 创建一个计数型信号量,返回它的句柄。
* 此函数内部会分配信号量结构体
* uxMaxCount: 最大计数值
* uxInitialCount: 初始计数值
* 返回值: 返回句柄,非 NULL 表示成功
*/
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t
uxInitialCount);
/* 创建一个计数型信号量,返回它的句柄。
* 此函数无需动态分配内存,所以需要先有一个 StaticSemaphore_t 结构体,并传入它的
指针
* uxMaxCount: 最大计数值
* uxInitialCount: 初始计数值
* pxSemaphoreBuffer: StaticSemaphore_t 结构体指针
* 返回值: 返回句柄,非 NULL 表示成功
*/
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphore
Buffer );
删除
对于动态创建的信号量,不再需要它们时,可以删除它们以回收内存
/*
* xSemaphore: 信号量句柄,你要删除哪个信号量
*/
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
give/take
在任务中使用 | 在ISR中使用 | |
---|---|---|
give | xSemaphoreGive | xSemaphoreGiveFromISR |
take | xSemaphoreTake | xSemaphoreTakeFromISR |
- xSemaphoreGive的函数原型如下:
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
参数 | 说明 |
---|---|
xSemaphore | 信号量句柄,用于指定释放哪个信号量 |
返回值 | pdTRUE 表示成功。如果二进制信号量的计数值已经是 1,再次调用此函数则返回失败; 如果计数型信号量的计数值已经是最大值,再次调用此函数则返回失败 |
- pxHigherPriorityTaskWoken的函数原型如下:
BaseType_t xSemaphoreGiveFromISR(
SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken
);
参数 | 说明 |
---|---|
xSemaphore | 信号量句柄,用于指定释放哪个信号量 |
pxHigherPriorityTaskWoken | 如果释放信号量导致更高优先级的任务变为就绪态,则*pxHigherPriorityTaskWoken = pdTRUE |
返回值 | pdTRUE 表示成功。如果二进制信号量的计数值已经是 1,再次调用此函数则返回失败;如果计数型信号量的计数值已经是最大值,再次调用此函数则返回失败 |
- xSemaphoreTake的函数原型如下
BaseType_t xSemaphoreTake(
SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait
);
参数 | 说明 |
---|---|
xSemaphore | 信号量句柄,用于指定获取哪个信号量 |
xTicksToWait | 若无法立即获取信号量,设置阻塞方式: 0:不阻塞,立即返回 portMAX_DELAY :一直阻塞直至获取成功其他值:阻塞的Tick个数,可使用 pdMS_TO_TICKS() 将阻塞时间指定为若干ms |
返回值 | pdTRUE 表示获取信号量成功 |
- xSemaphoreTakeFromISR的函数原型如下
BaseType_t xSemaphoreTakeFromISR(
SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken
);
参数 | 说明 |
---|---|
xSemaphore | 信号量句柄,用于指定获取哪个信号量 |
pxHigherPriorityTaskWoken | 若获取信号量导致更高优先级的任务变为就绪态,则*pxHigherPriorityTaskWoken = pdTRUE |
返回值 | pdTRUE 表示成功 |