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资源管理(信号量)的更多相关文章

  1. uc/os iii移植到STM32F4---IAR开发环境

    也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢 ...

  2. uC/OS - III 移植 IAR平台

    关于移植uC/OS-III 网上已经有很多教程了此处只是做个记录 首先下载源码然后解压得到下面的文件: 然后在模版工程里新建各种文件夹: 最后全部都添加进工程: OK了,编译一下,惊呆了,竟然 0错误 ...

  3. uC/OS II原理分析及源码阅读(一)

    uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...

  4. 基于μC/OS—III的CC1120驱动程序设计

    基于μC/OS—III的CC1120驱动程序设计 时间:2014-01-21 来源:电子设计工程 作者:张绍游,张贻雄,石江宏 关键字:CC1120   嵌入式操作系统   STM32F103ZE   ...

  5. 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II

    SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...

  6. uc/os 任务删除

    问题描述:     uc/os 任务删除 问题解决: uc/os任务删除流程图 具体代码 注:     如上是关中断,以及取消优先级对应的就绪标志 关中断代码为: 取消就绪标志,实际上是将就绪表中指定 ...

  7. uc/os任务创建

    问题描述:      uc/os中任务创建 问题解决: 创建一个任务,任务从无到有.任务创建函数分两种, 一种是基本的创建函数OSTaskCreate, 另一种是扩展的任务创建函数OSTaskCrea ...

  8. uC/OS 的任务调度解析 (转)

    uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS ...

  9. 关于uC/OS的简单学习(转)

    1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数, ...

  10. STM32F40G-EVAL_UC/OS III

    micrum官网下载uc/os程序包: 包含文件cotex_M4.h:

随机推荐

  1. What’s new for Spark SQL in Apache Spark 1.3(中英双语)

    文章标题 What’s new for Spark SQL in Apache Spark 1.3 作者介绍 Michael Armbrust 文章正文 The Apache Spark 1.3 re ...

  2. macOS 下 PHPStorm + Xdebug 调试 Docker 环境中的代码

    0x00 描述 宿主机是 mac mini,构建的项目在 docker 中,所以需要在 PHPStorm 上配置 Xdebug 进行远程代码调试. 0x01 环境 宿主机:macOS High Sie ...

  3. 查看哪个用户登录过服务器 记录 时间 和 ip

    who /var/log/wtmp 1>wtmp 一个用户每次登录进入和退出时间的永久纪录

  4. [转]论SOA架构的几种主要开发方式

    面向服务架构soa以其独特的优势越来越受到企业的重视,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署.组合和使用.服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理 ...

  5. Linux 文件属性及权限_007

    Linux一切皆文件: Llinux系统的文件或目录的属性主要包括:索引节点.文件类型.文件权限.链接数.所属的用户和用户组.最近修改时间等. Llinux文件属性及权限图形说明: Linux文件属性 ...

  6. Java 判断字符串 中文是否为乱码

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class ChineseUtill { private ...

  7. Idea2018旗舰版破解方法

    完整请参考 https://www.jianshu.com/p/3c87487e7121 1.在hosts文件里添加一行: 0.0.0.0 account.jetbrains.com 2.在Activ ...

  8. 解决使用微软模拟器VS Emulator for Android在VS2017 Xamarin开发中不能调试程序的问题。

    在使用VS2017 XAMARIN调试Android应用程序时,屏幕闪一下,进入不了调试(使用谷歌的模拟器可以调试,但是太慢), 我们现在来解决一下这个问题. 第一步:打开Hyper-V管理器 第二步 ...

  9. mac更改launchpad图标大小

    设置每列显示的图标数目为8 defaults write com.apple.dock springboard-columns -int 8设置每行显示的图标数目为7 defaults write c ...

  10. 【sql基础】按照名字分组查询时间最早的一条记录

    给出2种解决方案 rownumber SELECT * FROM ( SELECT IdentityID, OpenID, ROW_NUMBER() OVER(PARTITION BY OpenID ...