FreeRTOS之信号量
·
概述
- 信号量本质上也是一个队列,只不过不涉及数据传输,只涉及数据个数的加加减减,换句话说就是传递状态。使用信号量效率更高、更节省内存
- 分类
- 计数型信号量(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表示成功 |
「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!
更多推荐



所有评论(0)