UCOS-III笔记(七)

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习

擅长领域:驱动开发,嵌入式软件开发,BSP开发

作者主页:一个平凡而乐于分享的小比特的个人主页

文章收录专栏:UCOS-III,本专栏为UCOS-III学习记录

欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

UCOS-III笔记(七)

信号量

​ 一种解决同步问题的机制,可以实现对共享资源的有序访问

特点:

  1. 当计数值大于0,代表有信号量资源
  2. 当释放信号量,信号量计数值(资源数)加一
  3. 当获取信号量,信号量计数值(资源数)减一
  4. 信号量:用于传递状态
  5. 当信号量如果最大值被限定为1,那么它就是二值信号量;如果最大值不是1,它就是计数型信号量

二值信号量

​ 二值信号量实际上就只有空和满两种情况,所以称为二值。

​ 二值信号量通常用于互斥访问或任务同步, 与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转的问题 ,所以二值信号量更适合用于同步

使用二值信号量的过程:创建二值信号量 -> 释放二值信号量 -> 获取二值信号量

函数 描述
OSSemCreate() 创建一个信号量
OSSemDel() 删除一个信号量
OSSemPend() 获取信号量资源
OSSemPendAbort() 终止任务挂起等待信号量资源
OSSemPost() 释放信号量资源
OSSemSet() 强制设置信号量的资源数
OSSemCreate():创建一个信号量
c 复制代码
void OSSemCreate( 	OS_SEM *		p_sem,			//指向信号量结构体的指针
                 	CPU_CHAR *		p_name,			//指向作为信号量名的 ASCII 字符串的指针
                 	OS_SEM_CTR 		cnt,			//信号量资源数的初始值
                 	OS_ERR *		p_err  			//指向接收错误代码变量的指针
                )
OSSemPost():释放信号量
c 复制代码
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 类型返回值为信号量资源数更新后的值

OSSemPend():获取信号量
c 复制代码
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

计数型信号量适用场合:

  1. 事件计数

    当每次事件发生后,在事件处理函数中释放计数型信号量(计数值+1),其他任务会获取计数型信号量(计数值-1) ,这种场合一般在创建时将初始计数值设置为 0

  2. 资源管理

    信号量表示有效的资源数目。任务必须先获取信号量(信号量计数值-1 )才能获取资源控制权。当计数值减为零时表示没有的资源。当任务使用完资源后,必须释放信号量(信号量计数值+1)。信号量创建时计数值应等于最大资源数目

注意:计数型信号量和二值信号量的API函数是公用的

优先级翻转

  • 优先级翻转:高优先级的任务反而慢执行,低优先级的任务反而优先执行
  • 优先级翻转在抢占式内核中是非常常见的,但是在实时操作系统中是不允许出现优先级翻转的,因为优先级翻转会破坏任务的预期顺序,可能会导致未知的严重后果
  • 在使用二值信号量的时候,经常会遇到优先级翻转的问题

举个例子:

​ 高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度。但其他中等优先级的任务却能抢到CPU资源。从现象上看,就像是中优先级的任务比高优先级任务具有更高的优先权(即优先级翻转)

互斥信号量

​ 互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中!

​ 优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级。

​ 此时任务H的阻塞时间仅仅是任务L的执行时间,将优先级翻转的危害降到了最低,优先级继承并不能完全的消除优先级翻转的问题

​ 注意:互斥信号量不能用于中断服务函数中,原因如下:

  1. 互斥信号量有任务优先级继承的机制, 但是中断不是任务,没有任务优先级, 所以互斥信号量只能用于任务中,不能用于中断服务函数
  2. 中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态(中断要快进快出)

使用流程:创建互斥信号量 -> 获取信号量 -> 释放信号量

函数 描述
OSMutexCreate() 创建一个互斥信号量
OSMutexDel() 删除一个互斥信号量
OSMutexPend() 获取互斥信号量
OSMutexPost() 释放互斥信号量

注意:创建互斥信号量时,默认信号量有效

OSMutexCreate():创建一个互斥信号量
c 复制代码
void OSMutexCreate (	OS_MUTEX* 		p_mutex,		//指向互斥信号量结构体的指针
                    	CPU_CHAR *		p_name,			//指向作为信号量名的 ASCII 字符串的指针
                    	OS_ERR *		p_err 			//指向接收错误代码变量的指针
                   ) 
OSMutexPend():获取互斥信号量
c 复制代码
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 			//指向接收错误代码变量的指针
                    ) 
OSMutexPost():释放互斥信号量
c 复制代码
Void	OSMutexPost (	OS_MUTEX*		p_mutex, 		//指向互斥信号量结构体的指针
						OS_OPT 			opt,			//OS_OPT_POST_NONE:不指定特定的选项
                     									//OS_OPT_POST_NO_SCHED :禁止在本函数内执行任务调度
                     	OS_ERR *		p_err			//指向接收错误代码变量的指针
                    ) 
相关推荐
zore_c1 天前
【C语言】文件操作详解2(文件的顺序读写操作)
android·c语言·开发语言·数据结构·笔记·算法·缓存
狐571 天前
2025-12-03-LeetCode刷题笔记-3625-统计梯形的数目-II
笔记·leetcode
d111111111d1 天前
STM32低功耗学习-待机模式-(学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习
TL滕1 天前
从0开始学算法——第七天(快速排序算法)【面试高频】
笔记·学习·算法·面试·职场和发展·排序算法
重生之我在番茄自学网安拯救世界1 天前
网络安全中级阶段学习笔记(五):CSRF跨站请求伪造学习笔记(超全总结)
笔记·学习·网络安全·csrf·跨站请求伪造
浩瀚地学1 天前
【Java】方法
java·开发语言·经验分享·笔记
('-')1 天前
《从根上理解MySQL是怎样运行的》第二十三章笔记
数据库·笔记·mysql
丝斯20111 天前
AI学习笔记整理(28)—— 计算机视觉之姿态估计与动作识别
人工智能·笔记·学习
Xudde.1 天前
friendly2靶机渗透
笔记·学习·安全·web安全·php
摇滚侠1 天前
零基础小白自学 Git_Github 教程,GitHub Action 基础概念,笔记22
笔记·git·github