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. hive SQL 静态分区和 动态分区

    Hive 分区介绍: hive中简单介绍分区表(partition table),含动态分区(dynamic partition)与静态分区(static partition) hive中创建分区表没 ...

  2. Deep Dive into Spark SQL’s Catalyst Optimizer(中英双语)

    文章标题 Deep Dive into Spark SQL’s Catalyst Optimizer 作者介绍 Michael Armbrust, Yin Huai, Cheng Liang, Rey ...

  3. ComputeShader中Counter类型的使用

    接上一篇:https://www.cnblogs.com/hont/p/10122129.html 除了Append类型对应的Consume/AppendStructuredBuffer还有一个Cou ...

  4. Redis 分布式锁的实现

    0X00 测试环境 CentOS 6.6 + Redis 3.2.10 + PHP 7.0.7(+ phpredis 4.1.0) [root@localhost ~]# cat /etc/issue ...

  5. ServiceMesh究竟解决什么问题?

    服务网格(ServiceMesh)这两年异常之火,号称是下一代微服务架构,互联网公司经常使用的是微服务分层架构. 随着数据量不断增大,吞吐量不断增加,业务越来越复杂,服务的个数会越来越多,分层会越来越 ...

  6. Redis在C#中的使用及Redis的封装

    Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(string ...

  7. Spring钩子方法和钩子接口的使用详解

    本文转自:http://www.sohu.com/a/166804449_714863 前言 SpringFramework其实具有很高的扩展性,只是很少人喜欢挖掘那些扩展点,而且官方的Refrenc ...

  8. dma子系统 dmac

    DMA子是CPU中实现数据传输的一种方式,CPU配置好DMA控制器之后发起数据传输,CPU本身不参与数据传输的动作中去. DMA种类: 分为外设DMA和DMA控制器.其中外设DMA实现的为特定的外设与 ...

  9. 转载记录一个有效的jetbrains激活码

    来自:https://blog.csdn.net/ahun535915415/article/details/80687762 K03CHKJCFT-eyJsaWNlbnNlSWQiOiJLMDNDS ...

  10. vscode打造最佳的markdown编辑器

    参考:https://www.jianshu.com/p/18876655b452 在macos下也设置成功: