信号量即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.*/
卫士通荣获鲲鹏应用创新大赛2022四川赛区-openEuler赛道二等奖
GD32单片机STM32远程下载手机程序升级固件下载局域网网页升级工具
超简易音频放大器的制作
char和string在西门子PLC中的格式
STM32F4时钟配置的操作步骤
Semaphore信号量概念及其介绍
医疗生物技术领域得到人工智能加持将会更加可靠
恩智浦推出灵活的物联网云平台,用于边缘设备的安全管理和连接
日本企业加速研发下一代电池 索尼为首
科学家通过电子滤波器研发世界上最便宜的助听器,成本不到一美元
5G VR时代来临,微型超高清OLED微显示器带来非凡体验
医疗保健产品将亮相2013 CES,新型便携设备时代来临
达实智能节能服务打造标杆案例
三大运营商携号转网服务即将开启,用户该如何选择
关于新能源汽车的优势和劣势
感觉“全世界”都在为5G让路?
地平线与MINIEYE达成战略合作,构建乘用车、商用车双市场智能最优解
大联大品佳集团推出基于Microchip产品的车载USB快速充电解决方案
直线电机的优缺点 直线电机和伺服电机的区别
苹果正研发iPhone X Plus和iPhone X SE两款手机