信号量即Semaphore。信号量主要用于控制和保护任务对特定资源的访问。FreeRTOS的信号量分为二值信号量、计数型信号量和互斥信号量。其中互斥信号量即Mutex在CMSIS API中被独立;本文主要讲解二值信号量和计数型信号量。
在FreeRTOS中,二值信号量和计数信号量在创建方式和功能上没有差异,两者区别仅为二值信号量token数为1;而计数信号量token>1。
- 信号量工作原理
图示为CMSIS-RTOS的信号量抽象原理图。系统创建信号量,一并指定信号量内token(object)数量。线程(任务)可进行拿取/放入token的操作。
①放入token:线程可以向信号量中放入token。调用一次相应函数即放入一个。若当前信号量已满则报错。
②拿取token: 线程向信号量中拿取token。和消息队列一样,取操作可以设置阻塞超时时间。当消息量中无token时,线程进入**BLOCK**状态等待消息量被放入token。**在此期间当任务检测到消息量放入token时,将自动由****BLOCK**态转移为**READY**态。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从阻塞态转移为**READY**态。此时程序会返回**osErrorTimeout**错误。若没有设置**阻塞超时**且参数正确,返回**osErrorResource**错误**。**
- Semaphore APIs
①创建信号量
可以通过函数 **osSemaphoreNew() **创建信号量。在创建时,可以选择信号量可容纳token的数量、初始token数; 并且可以传入配置结构体。当创建失败时返回NULL。
当max_count为1时,将创建二值信号量。
osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);/*
@param: max_count -信号量可容纳token的数量
initial_count -信号量初始时刻含有的token数量;initial_count<=max_count
*attr -配置结构体
@retval -信号量ID(句柄);若创建失败返回NULL
*/
②获取信号量中token 【可在中断中使用】
※当在中断中使用该函数时,阻塞延时时间timeout应设置为0U,否则报Parameter错误。
线程调用该函数时,当消息量中无token时,线程进入BLOCK状态等待消息量被放入token。在此期间当任务检测到消息量放入token时,将自动由****BLOCK态转移为READY态。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从阻塞态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误**。**
osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout);/* 获取一个token
@param: semaphore_id -传入信号量ID(句柄)
timeout -阻塞延时时间
@retval:
osOK: 操作成功
osErrorTimeout: the token could not be obtained in the given time.
osErrorResource: the token could not be obtained when no timeout was specified.
osErrorParameter: the parameter semaphore_id is NULL or invalid.*/
timeout参数:
== 0U //不设置阻塞超时时间
== osWaitForever //任务将一直阻塞直到空队列被写入/满队列被取出数据
== Ticks //设置具体等待时间,单位为RTOS心跳数(Ticks)
③ 向信号量放入一个token 【可在中断中使用】
当信号量溢出时,函数返回**osErrorResource **。
osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id);/*放入一个token
@param: semaphore_id -传入信号量ID(句柄)
@retval:
osOK: the token has been released and the count incremented.
osErrorResource: the token could not be released (maximum token count has been reached).
osErrorParameter: the parameter semaphore_id is NULL or invalid.
*/
④获取状态
uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id);/*获取信号量中token数
*/
⑤清理(删除)信号量
osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id);/*
@retval:
osOK: the semaphore object has been deleted.
osErrorParameter: the parameter semaphore_id is NULL or invalid.
osErrorResource: the semaphore is in an invalid state.
osErrorISR: osSemaphoreDelete cannot be called from interrupt service routines.
*/
-
CMSIS
+关注
关注
0文章
40浏览量
11956 -
FreeRTOS
+关注
关注
12文章
484浏览量
62455 -
延时器
+关注
关注
1文章
36浏览量
15196 -
串口中断
+关注
关注
0文章
67浏览量
14023
发布评论请先 登录
相关推荐
转:freeRTOS信号量学习
第14章 信号量
信号量–使用许可的概念
信号量semphere概述
信号量机制怎么理解
![<b class='flag-5'>信号量</b>机制怎么理解](https://file1.elecfans.com//web2/M00/A6/E3/wKgZomUMQRaAdIqjAAAqdW6nQ38375.png)
Linux信号量(2):POSIX 信号量
浅谈鸿蒙内核源码的信号量运作原理
FreeRTOS 队列 信号量 互斥量
![FreeRTOS 队列 <b class='flag-5'>信号量</b> 互斥<b class='flag-5'>量</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
ThreadX(六)------信号量semaphore
![ThreadX(六)------<b class='flag-5'>信号量</b><b class='flag-5'>semaphore</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
评论