UCOSIII操作系统
UCOSIII其他内容导航不迷路
UCOSIII操作系统-简介
【UCOSIII操作系统】任务篇(1)创建任务
【UCOSIII操作系统】任务篇(2)相关API函数
【UCOSIII操作系统】系统初始化篇(1)系统初始化
【UCOSIII操作系统】系统初始化篇(2)CPU,SysTick,内存初始化
【UCOSIII操作系统】硬件初始化篇(1)硬件初始化以及开始运行系统
【UCOSIII操作系统】消息队列篇(1)消息队列
【UCOSIII操作系统】消息队列篇(2)任务消息队列
【UCOSIII操作系统】信号量与互斥量篇(1)信号量
【UCOSIII操作系统】信号量与互斥量篇(3)任务信号量
【UCOSIII操作系统】事件篇
【UCOSIII操作系统】中断管理篇
【UCOSIII操作系统】临界段篇
【UCOSIII操作系统】软件定时器篇
【UCOSIII操作系统】内存管理篇
已完结
说在前面:
这个内容不适合0基础的人,因为这里只讲了应用层面的东西,并没有深入内核讲解,所以要从零开始学UCOSIII的朋友,可以先去学完入门内容,再来观看这个笔记加深印象。
这篇文章是个人学习整理,如有错误请指正
UCOSIII操作系统——信号量与互斥量篇(1)互斥量
互斥量又称互斥信号量(本质也是一种信号量,不具备传递数据功能)
- 互斥信号量是一种特殊的二值信号量
- 它支持互斥量所有权、递归访问以及防止优先级翻转的特性
- 主要用于解决优先级翻转的问题
- 注意!只有任务才能使用互斥信号量(中断服务程序则不可以),UCOSIII允许用户嵌套使用互斥型信号量,一旦一个任务获得了一个互斥型信号量,则该任务最多可以对该互斥型信号量嵌套使用250次,当然该任务只有释放相同的次数才能真正释放这个互斥型信号量。
互斥量的API函数
函数 | 描述 |
---|---|
OSMutexCreate() | 创建一个互斥信号量(常用) |
OSMutexDel() | 删除一个互斥信号量 |
OSMutexPend() | 等待一个互斥信号量(常用) |
OSMutexPendAbort() | 取消等待 |
OSMutexPost() | 释放一个互斥信号量(常用) |
创建互斥信号量->OSMutexCreate()()
- 函数原型
void OSMutexCreate (OS_MUTEX *p_mutex, //互斥量指针
CPU_CHAR *p_name, //取互斥量的名称
OS_ERR *p_err) //返回错误类型
和信号量一样
互斥量控制块指针: 指向我们定义的互斥量量控制块结构体变量, 所以在创建之前我们需要先定义一个互斥量量控制块变量。
OS_MUTEX mutex; //声明互斥量
- 应用实例
OS_MUTEX mutex; //声明互斥量
/* 创建互斥量 mutex */
OSMutexCreate ((OS_MUTEX *)&mutex, //指向互斥量变量的指针
(CPU_CHAR *)"Mutex For Test", //互斥量的名字
(OS_ERR *)&err); //错误类型
删除互斥信号量-> OSMutexDel()
OSSemDel0)用于删除一个互斥量,互斥量删除函数是根据互斥量结构(互斥量句柄)直接删除的,删除之后这个互斥量的所有信息都会被系统清空,而且不能再次使用这个互斥量了,但是需要注意的是,如果某个互斥量没有被定义,那也是无法被删除的,如果有任务阻塞在该互斥量上,那么尽量不要删除该互斥量。想要使用互斥量删除函数就必须将OS_ CFG_ MUTEX _DEL_EN宏定义配置为1。
- 函数原型
#if OS_CFG_MUTEX_DEL_EN > 0u //如果使能了 OSMutexDel()
OS_OBJ_QTY OSMutexDel (OS_MUTEX *p_mutex, //互斥量指针
OS_OPT opt, //选项
OS_ERR *p_err) //返回错误类型
- 选项opt
OS_OPT_DEL_NO_PEND //如果只在没任务等待时删除互斥量
OS_OPT_DEL_ALWAYS //如果必须删除互斥量
等待一个互斥信号量->OSMutexPend()
使用该函数接口时,只有已持有互斥量所有权的任务才能释放它,当任务调用OSMutexPost()函数时会释放一次互斥量, 当互斥量的成员变量OwnerNestingCtr 为0的时候,互斥量状态才会成为开锁状态,等待获取该互斥量的任务将被唤醒。如果任务的优先级被互斥量的优先级翻转机制临时提升,那么当互斥量被完全释放后,任务的优先级将恢复为原本设定的优先级。
- 函数原型
void OSMutexPend (OS_MUTEX *p_mutex, //互斥量指针
OS_TICK timeout, //超时时间(节拍)
OS_OPT opt, //选项
CPU_TS *p_ts, //时间戳
OS_ERR *p_err) //返回错误类型
timeout: 指定等待互斥信号量的超时时间(时钟节拍数),如果在指定的时间内互斥信号量没有释放,则允许任务恢复执行。该值设置为0的话,表示任务将会-一直等待下去,直到信号量被释放掉。
opt: 用于选择是否使用阻塞模式。
OS_OPT_PEND_BLOCKING指定互斥信号量被占用时,任务挂起等待该互斥信号量。
OS_ OPT_ PEND_ NON_ BLOCKING指定当互斥信号量被占用时,直接返回任务。
注意!当设置为OS_ OPT_PEND_NON_BLOCKING,是timeout参数就没有意义了,应该设置为0。
p_ts: 指向一个时间戳,记录发送、终止或删除互斥信号量的时刻。.
- 应用实例
OSMutexPend ((OS_MUTEX *)&mutex, //申请互斥量 mutex
(OS_TICK )0, //无期限等待
(OS_OPT )OS_OPT_PEND_BLOCKING, //如果不能申请到互斥量就堵塞任务
(CPU_TS *)0, //不想获得时间戳
(OS_ERR *)&err); //返回错误类
释放一个互斥信号量->OSMutexPost()
我们可以通过调用函数OSMutexPost()来释放互斥型信号量,只有之前调用过函数OSMutexPend()获取互斥信号量,才需要调用OSMutexPost()函数来释放这个互斥信号量
- 函数原型
void OSMutexPost (OS_MUTEX *p_mutex, //互斥量指针
OS_OPT opt, //选项
OS_ERR *p_err) //返回错误类型
- 选项opt
用来指定是否进行任务调度操作
OS_OPT_POST_NONE 不指定特定的选项
OS_OPT_POST_NO_SCHED 禁止在本函数内执行任务调度操作。 - 应用实例
OS_MUTEX mutex; //声明互斥互斥量
OS_ERR err;
OSMutexPost ((OS_MUTEX *)&mutex, //释放互斥互斥量 mutex
(OS_OPT )OS_OPT_POST_NONE, //进行任务调度
(OS_ERR *)&err); //返回错误类型
详细代码可以参考正点原子
例10-5 UCOSIII互斥信号量