15.2-uC/OS-III资源管理(信号量)
1.信号量
信号量是一个“ 锁定机构”,代码需要获得钥匙才可以访问共享资
源。占用该资源的任务不再使用该资源并释放资源时,其它任务才能
够访问这个资源。
通常有两种类型的信号量:二值信号量和多值信号量。
(1).二值信号量
二值信号量的值只能是 0或 1.
(2).多值信号量
多值信号量计数值可以是 0到 4294967295(依赖于计数值是 8位, 16位或 32位)。
特别的, uC/OS-III中的信号量计数值最大为OS_SEM_CTR(见OS_TYPE.H)。
根据信号量计数值,uC/OS-III可以知道有该信号量可以再被多少个任务获得。
只有任务才允许使用信号量, ISR是不允许的。
2.信号量相关的函数
函数名 | 功能 |
OSSemCreate() | 创建一个信号量 |
OSSemDel() | 删除一个信号量 |
OSSemPend() | 等待某个信号量 |
OSSemPendAbort() | 取消等待某个信号量 |
OSSemPost() | 释放或标记信号量 |
OSSemSet() | 设置信号量计数值 |
3信号量需注意:
(1).用信号量访问共享资源不会导致中断延迟。当任务在执行信号量
所保护的共享资源时, ISR或高优先级任务可以抢占该任务。
(2).应用中可以有任意个信号量用于保护共享资源。然而,推荐将信
号量用于I/O端口的保护,而不是内存地址。
(3).信号量经常被过度使用。很多情况下,访问一个简短的共享资源
时不推荐使用信号量, 请求和释放信号量会消耗CPU时间。 通过关/
开中断能更有效地执行这些操作。
信号量会导致一种严重的问题:优先级反转。
4.优先级反转
优先级反转是实时系统中的一个常见问题,仅存在于基于优先级
的抢占式内核中。
( 1) 任务H( High优先级) 和任务M( Medium优先级) 都在
等待事件发生,任务L( Low优先级)正在被运行。
( 2)这时,任务L想申请信号量。
( 3)任务L访问共享资源。
( 4)任务H所等待的事件发生, uC/OS-III挂起任务L。
( 5)开始执行任务H。
( 6)现在任务H想要访问任务L所占用的共享资源(此时该
共享资源被任务L占用)。因为该资源被任务L占用,任务H 被放
入挂起队列中等待这个信号量被释放。
( 7)任务L被恢复并继续执行。
( 8)任务L被任务M抢占因为任务M所等待的事件发生。
( 9)任务M开始执行。
( 10)任务M执行完毕, uC/OS-III将CPU控制权交还给任务L。
( 11)任务L被执行。
( 12)任务L执行完毕并释放资源。 此时, 任务H获得该资源,
uC/OS-III上下文切换到任务H。
( 13)任务H开始执行。
可以看出,任务H在任务L后被执行,因为任务H等待任务L
所占用的资源。麻烦在于任务M抢占任务L,若任务M需要执行很
长时间,则任务H会被延迟很长时间才执行,这叫做优先级反转。
解决优先级反转:
可以通过提升任务L的优先级解决这种问题(只在该任务访问共
享资源时),访问结束后就恢复任务的优先级。任务L的优先级需要
被上升到任务H的优先级。
5.互斥信号量mutex
uC/OS-III支持一种特殊类型的二值信号量叫做mutex,用于解决
优先级反转问题。
( 1)任务H和任务M等待事件的发生,任务L被执行。
( 2)此时,任务L申请并获得一个 mutex。
( 3)任务L被执行。
( 4)任务H和任务M所等待的事件发生,任务L被抢占。
( 5)任务H开始执行。
( 6)任务H想要访问任务L占用的共享资源。考虑到任务L
占用这个资源, uC/OS-III提升任务L的优先级与任务H相同。这样
就防止了任务L被任务M抢占(被中等优先级的任务抢占)。
( 7)任务L继续访问这个资源, 但现在任务L的优先级等于任务
H的优先级。注意的是任务H被挂起因为它要等待任务L释放
mutex。换句话说,任务H被插入到mutex的挂起队列中。
( 8)任务L对共享资源的访问执行完毕并释放mutex。uC/OS-III
恢复任务L到原有的优先级。然后uC/OS-III将这个mutex交给任务
H。 {并不是任务L已经全部执行完毕,而是当它释放信号量时就会
发生调度而转到高优先级任务}
( 9)任务H开始执行。
( 10)任务H对共享资源的访问完毕,并释放这个mutex。
( 11)任务H继续执行。
( 12)任务H执行完毕。 uC/OS-III将CPU控制权交给任务M。
( 13) 任务M被执行。
mutex是一个内核对象,它被数据类型OS_MUTEX所定义,
(OS_MUTEX的原型是os_mutex,见OS.H)。应用中可以有任意个
mutex(仅限于处理器的RAM)。
只有任务才可以使用mutex( ISR不可以使用mutex)。
uC/OS-III允许任务嵌套占有mutex。如果任务获得mutex,那么
它可以嵌套获得这个mutex多达250次。该任务需要释放相同次数才
能释放掉这个mutex。
6.与mutex相关的函数
函数名 | 功能 |
OSMutexCreate() | 创建一个mutex |
OSMutexDle() | 删除一个mutex |
OSMutexPend() | 等待一个mutex |
OSMutexPendAbort() | 任务取消等待mutex |
OSMutexPost() | 释放mutex |
任务占用共享资源前必须获得mutex。通过调用OSMutexPend()
申请这个信号量。
注意:(1).mutex是二值信号量,所以没必要初始化计数值。
(2).任何时候mutex只能提供给一个任务。 事实上, 推荐当你申请
一个mutex时,最好不要申请其它内核对象。
7.死锁
死锁,就是两个任务互相等待对方所占用的资源的情况
可以用以下方式防止死锁:
1) 同一个时间不要申请多于一个mutex
2) 不要直接地申请mutex( 该申请放到器件驱动中和可重入函数中)
3) 在处理之前先获得全部所需要的mutex
4) 任务间以同样的顺序申请资源
当申请信号量或mutex时允许设置期限, 这样能防止死锁, 但是同样
的死锁可能稍后再次出现。
15.2-uC/OS-III资源管理(信号量)的更多相关文章
- uc/os iii移植到STM32F4---IAR开发环境
也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢 ...
- uC/OS - III 移植 IAR平台
关于移植uC/OS-III 网上已经有很多教程了此处只是做个记录 首先下载源码然后解压得到下面的文件: 然后在模版工程里新建各种文件夹: 最后全部都添加进工程: OK了,编译一下,惊呆了,竟然 0错误 ...
- uC/OS II原理分析及源码阅读(一)
uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...
- 基于μC/OS—III的CC1120驱动程序设计
基于μC/OS—III的CC1120驱动程序设计 时间:2014-01-21 来源:电子设计工程 作者:张绍游,张贻雄,石江宏 关键字:CC1120 嵌入式操作系统 STM32F103ZE ...
- 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II
SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...
- uc/os 任务删除
问题描述: uc/os 任务删除 问题解决: uc/os任务删除流程图 具体代码 注: 如上是关中断,以及取消优先级对应的就绪标志 关中断代码为: 取消就绪标志,实际上是将就绪表中指定 ...
- uc/os任务创建
问题描述: uc/os中任务创建 问题解决: 创建一个任务,任务从无到有.任务创建函数分两种, 一种是基本的创建函数OSTaskCreate, 另一种是扩展的任务创建函数OSTaskCrea ...
- uC/OS 的任务调度解析 (转)
uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS ...
- 关于uC/OS的简单学习(转)
1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数, ...
- STM32F40G-EVAL_UC/OS III
micrum官网下载uc/os程序包: 包含文件cotex_M4.h:
随机推荐
- 给页面点击链接加了转圈圈和解决遇到的bug
今天遇到一个问题,之前给整个网站上的链接加了loading,今天遇到在ios的chrome和safari下点击进入新页面然后点击浏览器的返回按钮,loading还在,并且一直存在,最后网上搜到了解决方 ...
- vux安装中遇到的坑(转)
1.输入 npm install vux --save 2.输入 npm install vux-loader --save-dev(没安装的时候,会一直报错) 3.build/webpack.bas ...
- unicode、utf8、字符串字面值
发现好多新人都不明白,或者说没有直观的感受,其实很简单. 简单的说,unicode是一种将全球文字都涵盖的字典 - 可以认为每个字符都有一个数字索引. 比如可以这样(假设):'a' 的索引是13,'我 ...
- [转]SpringMVC+ Mybatis 配置多数据源 + 手动切换数据源
正确可行的解决方法:使用Spring提供的AbstractRoutingDataSource类来根据请求路由到不同的数据源.具体做法是先设置两个不同的dataSource代表不同的数据源,再建一个总的 ...
- websocket Tomcat JSP Demo
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 如何写Emit代码
写Emit代码也不是想象中的那么复杂,基本过程就是先手工写好C#代码,编译得到Exe或者Dll,然后用ILDASM或反编译工具,得到IL代码,最后就是看着IL代码,用Emit一个个对应发出代码,就行了 ...
- Apache kylin的基础环境
一.Apache kylin的基础环境 由于Apache kylin上的OLAP(wiki:OLAP)是构建在hadoop生态环境上的,所以hadoop环境的稳定性和健壮性对kylin的稳定运行至关重 ...
- L - Father Christmas flymouse
来源poj3160 After retirement as contestant from WHU ACM Team, flymouse volunteered to do the odds and ...
- JAVA课程课后作业03之动手动脑
一.构造函数 问题一: 错误代码如图: 错误原因:从图片中的编译报错的地方来看,程序是在给新的对象分配空间是出现了问题,因而我们往下观察Foo类,Foo类的构造方法是有一个参数的有参方法,而前面构造新 ...
- Centos 为Nginx 搭建https
Youtube Nginx 扩展模块 certbot文档 yum -y install epel-release yum -y install certbot certbot certonly --s ...