
本帖最后由 baiyongbin2009 于 2014-12-17 16:24 编辑 5 D6 Z }' i. o + b. N- \7 T& E, ?1 A! _ 第3章 基于时间触发的混合式调度器 9 |( z, P' x& f6 y3 A: M% c 本期教程带领大家学习混合式调度器的设计和使用方法,有了第2期合作式调度器的基础,本期教程的混合式调度器也相对比较容易。 3.1 抢占式调度器介绍 3.2混合式调度器介绍 3.3混合式调度器设计 3.4实验说明 3.5实验总结 3.1 抢占式调度器介绍 在上期教程,我们简单的介绍了抢占式调度器,本期教程再做进一步的讨论,主要集中于抢占式调度器的优缺点的讨论,让大家对抢占式调度器有一个更加深入的了解。 先来说一下抢占式调度器的特性(来自时间触发嵌入式模式这本书,这里说的特性和现在常用的小型RTOS有些区别),进而引出我们要讨论的问题: 抢占式调度器 l 抢占式调度器提供了一种多任务的系统结构 操作: l 任务在特定的时刻被调度运行(以周期性或者单次方式) l 当任务需要运行的时候,被添加到等待队列。 l 等待的任务(如果有的话)运行一段固定的时间,如果没有完成,将被放回到等待队列。然后下一个等待任务将会运行一段固定的时间,以此 类推。 实现: l 这种调度器相对复杂,访问共享资源时,要防止冲突。 l 该调度器必须为强占任务的所有中间状态分配存储器。 l 该调度器通常将(至少部分)由汇编语言编写。 l 该调度器通常作为一个独立的系统被创建。 性能: l 对外部事件的响应速度快 可靠性和安全性: l与合作式任务相比,通常认为更不可预测,并且可靠性低。 使用抢占式调度器最大的好处是对外部事件的快速响应,提高系统的实时性。带来好处的同时也是要付出代价的,下面就举一个例子,这个例子比较典型。 假设系统中的一个任务要从ADC端口读取模拟信号,这时发生了上下文切换,另一个任务也要访问这个端口,在这种情况下如果不采取措施阻止这种情况,数据将可能丢失或者破坏。这种问题往往出现在多任务平台中所谓的“临界段”,这些代码段一旦开始就必须不中断地运行,直到跑完这段代码。临界段还有很多,比如: l 读取或者修改变量(特别是任务间通信的全局变量)的代码,一般来说这时最常见的关键代码。 l 如果读过μCOS-II或μCOS-III源代码的话,会发现里面很多地方都做了开关中断的处理,就是为了防止多任务造成错误。 l 调用公共函数的代码,特别是不可重入的函数,如果多个任务都访问这个函数,结果是可想而知的。 解决这种情况最常用的的办法就是在临界段做开关中断处理,这种情况是最影响实时性的,如果关中断期间发生了外部中断事件,那么这个中断事件只有临界段执行完之后才能得到相应。还有一种解决办法就是使用调度锁,这样在一定程度上能够提供任务的实时性,在发生外部中断的时候会得到相应,但是不会发生任务切换,必须等到调度锁被解开。 关于抢占式调度器和合作式调度器到底谁好,在嵌入式领域没有一个定论,要根据自己的时间应用选择,很多嵌入式领域的专家都发表过这方面的文章,有兴趣的可以找找深入研究下,下面是Michael J. Pont的观点,原话如下: * P4 e! S: {1 O6 c& V5 q" B: u9 v Finally, it should be noted that the reasons why pre-emptive schedulershave been more widely discussed and used may not be for technical reasons atall: in fact, the use of pre-emptive environments can be seen to have clearcommercial advantages for some companies. For example, a co-operative schedulermay be easily constructed, entirely in a high-level programming language, inaround 300 lines of ‘C’ code, as we demonstrate in Chapter 9. The code ishighly portable, easy to understand and to use and is, in effect, freelyavailable. By contrast, the increased complexity of a preemptive operatingenvironment results in a much larger code framework (some ten times the size,even in a simple implementation: Labrosse, 1998). The size and complexity ofthis code makes it unsuitable for ‘in-house’ construction in most situations andtherefore provides the basis for a commercial ‘RTOS’ products to be sold,generally at high prices and often with expensive run-time royalties to bepaid. The continued promotion and sale of such environments has, in turn,prompted further academic interest in this area. 上面这段话的意思是说,抢占式调度器被广泛的讨论和使用的原因可能并不完全是技术上的问题,实际上对于一些公司来说,使用抢占式平台有明显的商业上的好处,这个该怎么理解呢?比如我们做了一款产品,产品的系统是用的μCOS-II。我们肯定会在说明书中宣称我们使用的是μCOS-II系统,因为这个系统已经得到了业界的认可,而不会使用我们自己的设计的系统,用户在购买产品的时候肯定会首选用μCOS-II设计的系统。如果使用合作式调度器,只需要300行左右的C代码就可以实现一个合作式调度器,这些代码的可移植性非常好,易于理解和使用,并且实际上是免费使用的。相比而言,抢占式运行环境增加了复杂性,从而导致更复杂的代码结构。在大多数情况下,这些代码的复杂性和长度使其不适合于普通开发人员自己构建,因此提供了商业实时操作系统的产品的销售基础。抢占式调度器通常价格比较贵,而且还需占用很大的实时开销。这些平台持续不断的宣称和销售反过来又促进了这个领域的更进一步的学术研究。 关于抢占式调度器就跟大家讲这么多,更深入的东西我们会在讲解μCOS-III源码的时候再跟大家分析。 7 i2 F# t& o k9 ` |
/ z1 L- \& P0 m( t
3.3.4 添加任务函数
& k/ z1 v' j: l$ c L3 m$ g% V" N
3.3.5 调度函数
. j1 m+ O: [: m+ v3 [* p4 u4 `
+ Z' b( F* z% _% {1 d8 P' r
" V8 v; [" t* d: [: P