uCOS-II中的任务切换-图解多种任务调度时机与问题
【@.1 任务调度时机】
之前的一篇文章分析了具体的uCOS-II中的任务切换机制,是从函数调用的角度上分析的。这次我具体从整个程序运行的时间上来看,分析多种任务调度发生的时机。以下所有图片均可点击放大观察。
所有图中红色箭头表示中断级的任务切换,蓝色箭头表示任务级的中断切换。
1. 仅有一个任务,这种情况最简单。假设时钟节拍是1000次每秒,由定时中断产生,当节拍的时钟服务程序结束时会调用OSInitExit,退出中断,其中 将进行上下文切换,运行当前就绪状态优先级最高的任务,这里当然就是任务A、任务A中的代码比较简单,运行到最后时假设调用OSTimeDly(1)延时 一个周期,提示系统放弃CPU控制权,这时将进行任务切换到空闲任务Idle Task。空闲任务优先级最低,是一个死循环,仅仅让一个OSIdleCtr循环一次加一。可以看出,在一个时钟节拍的间隔,这个计数器可能加不止一次。 另外uCOS中还有一个统计任务,需配置打开,其中就是利用这个空闲计数器求出CPU有多少时间在空闲任务中,即有多少CPU占空比。通过图示分析可以看 出,很明显虽然任务A延时一个时钟周期,1ms,但是实际上将会少于1ms的延时。这就是为什么实际的延时中或多或少都会有延时抖动的现象,下面的很多例 子的延时抖动都可能比这种情况更加复杂。
2. 简单的中断,这里假设有一个外部中断,在图示处打断了任务A的运行。外部中断响应后进入服务函数,中断退出时调用OSInitExit进行任务切换,回到 刚才被中断的任务。所以刚才的任务A就被延后了一段时间允许,之后任务A再切换到空闲任务。很明显,这个时钟周期内空闲计数器OSIdleCtr会少加一 些,最后可以统计出CPU占用率会上升一些。
3. 中断函数中利用OSSemPost发送一个信号量,接受信号量的是任务B,其优先级大于任务A。于是在每次中断服务函数结束时会首先调度任务B执行,按照 图中任务B的代码只有一个OSSemPend可能会有等待挂起发送,之后任务B会因为等待接受信号量而调度会任务A继续执行。图中的画出了三个外部中断分 别出现在不同时期,其中第三个外部中断将导致任务B执行到一半遇到时钟节拍的产生。这时候任务B会挂起,将执行节拍中断服务程序,经过调度后会发现任务B 任然处于就绪状态,所以将继续运行任务B直到结束。最后这里可以看出空闲任务在每个时钟周期被挤得更少了,所以CPU的利用率更多。
4. 跟第三中情况类似,只不过这里任务B中加了一句OSTimeDly(3)延时3个时钟周期,这时可以知道,在任务B延时期间,只剩TaskA和空闲任务, 他们将不会因为任务B的延时而被挂起。延时结束时,时钟节拍将首先调度延时结束处于就绪状态的任务B,之后再运行原本的任务A。这种情况也简单的表示了 uCOS是怎样充分利用CPU资源的。
5.中断中调用OSTaskResume恢复任务B。这里只是想说明,Resume/Suspend跟Post/Pend的区别,前者是一旦恢复则一直运行,而后者是Post一次,Pend方运行一次。
6. 当用信号量通讯时,利用任务A来发送,控制高优先级的任务B接受信号量。可以看出,任务A发送一次信号量将会时任务B调度执行,此时任务A由于优先级低, 被挂起,当任务B运行一次循环后又Pend等待信号量,这时任务B被挂起,由下一个时间周期的任务A发送,周而复始。
7. 对于共享资源,可以采用图示方式编写。这种方式表明,当两个任务想要使用共享资源时,每个任务用Pend和Post的组合包围住想要操作的资源(比如一个 函数,一个公共变量)。其中一个任务用完资源后执行Post,将会使另一个Pend等待资源的任务得以往下执行,不论二者的优先级如何。图中的任务也包含 了每次时钟节拍对任务的延时作用。不过像这种信号量通讯的场合会涉及到优先级反转问题,我们后面会分析。
8. 这里演示了一个比较恶劣的中断嵌套实例,可以看出所有任务/中断级的任务调度只有等最后一层中断嵌套执行结束后才能执行,在中断嵌套中若使用Post或 Resume想要执行任务调度也只能等到嵌套结束才能执行。uCOS-II支持中断嵌套,不用担心中断的响应问题,但是一旦中断嵌套之后就会出现很多延时 的问题,将会导致整个系统的实时性下降,比如图示的TaskA就因为中断嵌套,并且因为中断嵌套结束后TaskB接受到信号量而执行,使得其延时效果大大 超出我们想象,而且中间还缺了一步时钟周期,甚至导致这个周期满负荷(空闲任务不会执行到)。虽然画的有点夸张,但是这不得不引起我们的注意。所以通常推 荐中断服务函数写的越短越好,一个好的方法是,清除了中断标志后仅仅发送一个信号量通知别的任务执行,将所有需要花时间运行的工作交给任务而不是留给中断 服务函数处理。
以上的分析包含了少量几个任务和间可能出现的常见情况,对于大型程序来说,任务的调度和中断的响应可能比这个更加复杂,需要更进一步分析。
【@.2 优先级反转】
图 示的情况将出现优先级反转。任务A和C需要处理一个共享资源,低优先级的任务C首先得到信号量,处理完成后Post发送信号量通知等待中的任务A得以运 行,任务A处理完共享信号量后Post,将使得等待中的任务C运行,而过了一段时间,任务B由于某种原因被恢复为就绪状态,则任务B会抢夺任务C的CPU 使用权,待任务B结束后任务C才得以进行,之后任务C发送信号量,通知任务A得以继续运行。
这将会使得任务A等待信号量的时间延长,看上去是优先级低于A的任务B先于任务A执行,这往往也是我们所不希望的。这个问题的原因就是因为任务C的优先级太低,所以解决这个问题时简单的方法就是动态修改进行共享资源操作的任务的优先级即可。于是引入了互斥信号量。
互 斥信号量跟普通信号量基本一致,区别在于通过Pend得到信号量的任务将会被动态修改其优先级。这里我们一般会设置一个比较高的优先级,如图所示,任务A 和任务C交替得到信号量,并且得到信号量时被赋予了一个更高的优先级。这时若任务B进入就绪状态就无法得以运行了。注意到这仅仅是uCOS-II的解决方 法,因为uCOS-II不支持多任务同一优先级。
【@.3 uCOS中的中断延时】
对于中断响应的问题,从硬件上每个CPU并不相同,可以参考我的这篇文章对ARM7系列的中断响应进行一个了解。而uCOS对于中断响应会有一套自己的办法进行统一处理。
之前分析的内容仅仅是从任务级别来进行分析,但实际上更深入一步分析,中断的响应,任务的响应都会有一定时间的延时,以图示为例。
当 一个任务运行中得到中断请求,会首先有一个硬件的响应时间。之后硬件会关闭中断标志,一般是在CPU的状态寄存器中的IRQ位置1禁止,随后跳入中断入口 地址。之后uCOS会进行自己的特殊处理,对中断进行接管。首先会保存CPU当前寄存器,并通知内核进入中断函数(一般是调用OSInitEnter函 数),之后编写代码重新打开中断,允许中断嵌套。之后将进入中断服务函数。这期间的时间就是中断响应时间。
当服务函数结束后,会调用OSInitExit进行任务调度。若此时有新的任务置于就绪状态并且优先级比原任务高,则将会进行上下文切换,恢复CPU寄存器,中断返回后进入新的任务执行。若没有心的高优先级任务,则会原路返回,回到原来的任务继续执行。
可以很明显的看到,经过uCOS接受的中断响应将变慢,但是由于这样能实现中断嵌套和丰富的任务调度,所以这样的中断延时是可以接受的。
uCOS-II中的任务切换-图解多种任务调度时机与问题的更多相关文章
- DE1-SOC开发板上搭建NIOS II处理器运行UCOS II
DE1-SOC开发板上搭建NIOS II处理器运行UCOS II 今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...
- iOS7中的ViewController切换
转自:https://onevcat.com/2013/10/vc-transition-in-ios7/ iOS 7 SDK之前的VC切换解决方案 在深入iOS 7的VC切换效果的新API实现之前, ...
- Quartus II中FPGA的管脚分配保存方法
一.摘要 将Quartus II中FPGA管脚的分配及保存方法做一个汇总. 二.管脚分配方法 FPGA 的管脚分配,除了在QII软件中,选择“Assignments ->Pin”标签(或者点击按 ...
- LTE 切换过程中的数据切换
http://blog.sina.com.cn/s/blog_673b30dd0100j4p4.html LTE中的切换,根据无线承载(Radio Bearer)的QoS要求的不同,可以分为无缝切换( ...
- 在Quartus II中分配管脚的两种常用方法
在Quartus II中分配管脚的两种常用方法 示范程序 seg7_test.v 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* * ...
- 如何在Quartus II中设置Virtual pin
为了验证FPGA工程中的某个模块的功能和时序的正确性,常常需要对其单独进行验证,但是这些模块通常都与内部的众多信号相连(如系统总线,中断信号线等),往往一个模块的对外接口引脚会多达几百个,对其单独仿真 ...
- Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程
最近在面试Android,今天出了一个这样的题目,即如题: 我当时以为生命周期是这样的: onCreate --> onStart -- ---> onResume ---> onP ...
- sql server中创建链接服务器图解教程
转自sql server中创建链接服务器图解教程 1.展开服务器对象-->链接服务器-->右击"新建链接服务器" 注意:必须以数据库管理员身份登录(通常也就是sa帐号) ...
- 如何进行fragment中的来回切换?
本文选自StackOverflow(简称:SOF)精选问答汇总系列文章之一,本系列文章将为读者分享国外最优质的精彩问与答,供读者学习和了解国外最新技术,本文为大家讲解如何进行fragment中的来回切 ...
随机推荐
- 【深入理解JAVA虚拟机】第二部分.内存自动管理机制.4.JVM工具
1.概述 工具作用:性能监控与故障处理 工作原理:分析数据 数据包含:运行日志. 异常堆栈. GC日志. 线程快照(threaddump/javacore文件). 堆转储快照(heapdump/hpr ...
- Effective Java 第二版 Enum
/** * Effective Java 第二版 * 第30条:用enum代替int常量 */ import java.util.HashMap;import java.util.Map; publi ...
- ZT 设计模式六大原则(5):迪米特法则
转贴: 设计模式六大原则(5):迪米特法则 原帖子的后续评论里面很多值得仔细去看 切记!像21楼 21楼 chenshufei2 2012-09-23 12:47发表 [回复] 上个例子,就是方法 ...
- NODE-环境变量的配置(踩坑总结)
初学Node.js,从官网下载了node.js的Windows Installer,安装完成后,通过控制台输入node命令,发现提示说“node"不是内部或外部命令,这通常是由于没有设置环境 ...
- XAMPP中Apache因为端口原因不能启动的解决方法
在开启XAMPP的Apache时报出如下错误信息: 9:08:14 PM [Apache] Error: Apache shutdown unexpectedly.9:08:14 PM [Apache ...
- [转]Activitys, Threads, & Memory Leaks
转自:http://www.androiddesignpatterns.com/2013/04/activitys-threads-memory-leaks.html http://www.cnblo ...
- 开源项目之防火墙 tdifw
tdifw是windows防火墙软件(TDI层驱动过滤),负责监控网络监听与连接.以及过滤信息. 源码在src目录, 程序在Bin目录,执行根目录下的批处理文件也可以,具体步骤如下: 1. 运行ins ...
- 学会WCF之试错法——客户端调用基础
1当客户端调用未返回结果时,服务不可用(网络连接中断,服务关闭,服务崩溃等) 客户端抛出异常 异常类型:CommunicationException InnerException: Message: ...
- ESlint 语法检测配置说明
部分vue-cli脚手架创建的默认eslint规则: 代码末尾不能加分号 ; 代码中不能存在多行空行 tab键不能使用,必须换成两个空格 代码中不能存在声明了但未使用的变量 关闭eslint 这里只说 ...
- [Raspberry]001Ubuntu下查看linux版本,内核版本,系统位数,gcc版本
1. 查看linux版本 sunny@ubuntu:~$cat /etc/issueUbuntu 11.04 \n \l 2. 查看内核版本1) sunny@ubuntu:~$ cat /proc/ ...