🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习 🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发 ❄️作者主页:一个平凡而乐于分享的小比特的个人主页 ✨收录专栏:UCOS-III,本专栏为UCOS-III学习记录 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖
一种解决同步问题的机制,可以实现对共享资源的有序访问
特点:
二值信号量实际上就只有空和满两种情况,所以称为二值。
二值信号量通常用于互斥访问或任务同步, 与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转的问题 ,所以二值信号量更适合用于同步!

使用二值信号量的过程:创建二值信号量 -> 释放二值信号量 -> 获取二值信号量
函数 | 描述 |
|---|---|
OSSemCreate() | 创建一个信号量 |
OSSemDel() | 删除一个信号量 |
OSSemPend() | 获取信号量资源 |
OSSemPendAbort() | 终止任务挂起等待信号量资源 |
OSSemPost() | 释放信号量资源 |
OSSemSet() | 强制设置信号量的资源数 |
void OSSemCreate( OS_SEM * p_sem, //指向信号量结构体的指针
CPU_CHAR * p_name, //指向作为信号量名的 ASCII 字符串的指针
OS_SEM_CTR cnt, //信号量资源数的初始值
OS_ERR * p_err //指向接收错误代码变量的指针
)OS_SEM_CTR OSSemPost( OS_SEM * p_sem, //指向信号量结构体的指针
OS_OPT opt, //函数操作选项:
//OS_OPT_POST_1:只给一个任务(最高优先级的)发信号 //OS_OPT_POST_ALL:给所有等待该信号量的任务发信号
//以下宏可以与上面两个搭配使用
//OS_OPT_POST_NO_SCHED :禁止在本函数内执行任务调度
OS_ERR * p_err //指向接收错误代码变量的指针
) OS_SEM_CTR 类型返回值为信号量资源数更新后的值
OS_SEM_CTR OSSemPend( OS_SEM * p_sem, //指向信号量结构体的指针
OS_TICK timeout, //任务挂起等待信号量的最大允许时间,当为0时,表示将一直等待,直到接收到信号
OS_OPT opt, //OS_OPT_PEND_BLOCKING :如果信号量没有资源的话就阻塞任务 //OS_OPT_PEND_NON_BLOCKING :如果信号量没有资源任务就直接返回
CPU_TS * p_ts, //指向接收信号量接收时的时间戳的变量的指针
OS_ERR * p_err //指向接收错误代码变量的指针
) OS_SEM_CTR 类型返回值为信号量资源数更新后的值
计数型信号量与二值信号量是很相似的 ,但是计数型信号量的资源数大于1,也就是它的资源不止0和1
计数型信号量适用场合:
注意:计数型信号量和二值信号量的API函数是公用的
举个例子:

高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度。但其他中等优先级的任务却能抢到CPU资源。从现象上看,就像是中优先级的任务比高优先级任务具有更高的优先权(即优先级翻转)
互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中!
优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级。

此时任务H的阻塞时间仅仅是任务L的执行时间,将优先级翻转的危害降到了最低,优先级继承并不能完全的消除优先级翻转的问题
注意:互斥信号量不能用于中断服务函数中,原因如下:
使用流程:创建互斥信号量 -> 获取信号量 -> 释放信号量
函数 | 描述 |
|---|---|
OSMutexCreate() | 创建一个互斥信号量 |
OSMutexDel() | 删除一个互斥信号量 |
OSMutexPend() | 获取互斥信号量 |
OSMutexPost() | 释放互斥信号量 |
注意:创建互斥信号量时,默认信号量有效
void OSMutexCreate ( OS_MUTEX* p_mutex, //指向互斥信号量结构体的指针
CPU_CHAR * p_name, //指向作为信号量名的 ASCII 字符串的指针
OS_ERR * p_err //指向接收错误代码变量的指针
) void OSMutexPend ( OS_MUTEX* p_mutex, //指向互斥信号量结构体的指针
OS_TICK timeout, //任务挂起等待信号量的最大允许时间
OS_OPT opt, //OS_OPT_PEND_BLOCKING :如果信号量没有资源的话就阻塞任务 //OS_OPT_PEND_NON_BLOCKING :如果信号量没有资源任务就直接返回
CPU_TS * p_ts, //指向接收互斥信号量接收时的时间戳的变量的指针
OS_ERR * p_err //指向接收错误代码变量的指针
) Void OSMutexPost ( OS_MUTEX* p_mutex, //指向互斥信号量结构体的指针
OS_OPT opt, //OS_OPT_POST_NONE:不指定特定的选项
//OS_OPT_POST_NO_SCHED :禁止在本函数内执行任务调度
OS_ERR * p_err //指向接收错误代码变量的指针
)