嵌入式系统的多道程序技术

来源:互联网 发布:湘潭湖南软件职业学院 编辑:程序博客网 时间:2024/06/07 14:59

概述

嵌入式操作系统可以分为两种类型:单道程序设计多道程序设计。所谓单道程序设计,就是在操作系统当中,在任何时候只能有一个程序在运行。所谓多道程序设计,就是在操作系统当中,允许多个程序同时存在并运行。在现代操作系统当中,为了提高系统资源的利用率,普遍采用了多道程序技术。在多到程序技术中,大多数传统操作系统是使用进程或者线程技术。

任务

与传统的操作系统不同,在许多嵌入式操作系统当中,并没有使用“进程”或“线程” 这两个术语,而是把能够独立运行的实体称为“任务”(task)。那么这里所说的任务到底是进程还是线程呢?对于不同的系统,这个问题有不同的回答。因此,当我们在研究一个 具体的嵌入式操作系统的时候,要注意加以区分。

任务的状态

在多道程序系统中,任务是独立运行的实体,需要参与系统资源的竞争,只有在所需资源都得到了满足的情形下,才能在CPU上运行。因此,任务所拥有的资源情况是在不断变化的,这导致任务的状态也表现出不断变化的特性。不同的嵌入式操作系统对任务状态的定义不尽相同,但是一般来说,它们都会具备一下的三种基本状态。
运行状态(running):任务正在CPU上运行。
就绪状态(ready):任务已经具备了运行的条件,但是由于CPU正在运行其他的任务,所以暂时不能运行。只要CPU空闲下来,此任务就能运行。
阻塞状态(blocked):也叫等待状态(waiting),任务正在等在某种事件的发生的暂时不能运行。此时即使CPU空闲下来,此任务也不能运行。
对于就绪状态和阻塞状态,它们的相同之处在于,任务都是处于暂停状态,没有运行;不同之处在于,它们暂停的原因不一样,导致就绪状态的原因是外因,是操作系统不给CPU时间,导致阻塞状态的原因是内因,是任务自身的问题。

任务控制块

从操作系统的角度来说,它是如何来设计和实现任务机制的呢?是如何来进行任务管理的呢?答案就是任务控制块(Task Control Block,TCB),任务管理就是通过对各个任务的TCB的操作来实现的。
所谓TCB,就是在操作系统当中,用来描述和管理一个任务的数据结构。系统为每一个任务都维护了一个相应的TCB,用来保存该任务的各种相关信息。TCB内容主要包括一下几项:
- 任务的管理信息:包括任务的标识ID、状态、优先级、调度信息、时间统计信息、各种队列指针等。
- CPU上下文信息:各种CPU寄存器的当前值
- 资源管理信息
有了TCB这个数据结构以后,当需要创建一个新任务的时候,就为它初始化一个TCB,当需要终止一个任务的时候,只要回收它的TCB就可以了。对任务的组织和管理,就是对它们的TCB的组织和管理。

任务切换

假设一个任务正在CPU上运行,这时由于某种原因,系统决定调度另一个任务去运行,那么在这种情形下,就要进行一个任务切换(context switching),把当前任务的运行上下文保存起来,并恢复新任务的上下文。
任务切换通常具有如下基本步骤:
1. 将任务处理器的运行上下文保存在当前任务的TCB中。
2. 更新当前任务的状态,从运行状态变为就绪状态或阻塞状态。
3. 按照一定的策略,从处于就绪状态的任务选择一个运行。
4. 修改新任务的状态,从就绪状态变成运行状态。
5. 根据新任务的TCB内容,恢复它的运行上下环境。

任务队列

如前所述,在一个多任务的操作系统当中,各个任务的状态是经常变化的,有时处于运行状态,有时处于就绪状态,有时又处于阻塞状态。即便同是阻塞状态,引发阻塞的原因可能又各不相同,有的是因为等待I/O 操作,有的是因为任务之间的同步。因此,在一个操作系统当中,采用什么样的方式来组织它的所有任务,将直接影响到对这些任务的管理效率。
通常的做法是采用任务队列的方式。也就是说,由操作系统来维护一组队列,用来表示系统当中所有任务的当前状态。不同的状态用不同的队列来表示。例如,处于运行状态的所有任务构成了运行队列,处于就绪状态的所有任务构成了就绪队列,而对于处于阻塞状态的任务,则要根据它们阻塞的原因,分别构成相应的阻塞队列。

任务的调度

在多道程序操作系统中,经常会出现多个任务同时去竞争CPU的情况。换句话说,就是在系统的就绪队列中,有两个或多个任务同时处于就绪状态。假设在系统中只有一个CPU并且已经空闲下来了,现在的问题就是,对于就绪队列当中的那些任务,应该选择哪一个去运行呢?在操作系统当中,负责去做出这个选择的那一部分程序,就称为调度器(scheduler),而调度器在决策过程中所采用的算法,就称为调度算法。

调度的时机

任务调度的首要问题是何时进行调度,即调度发生的时机。一般来说有以下几种情况会发生任务的调度。
任务创建时,是执行新任务还是继续父任务?
任务结束时,从就绪队列选择某个任务执行,如果没有,则一般会调度一个特殊的空闲任务。
任务阻塞时,CPU必须另选一个任务运行。
当一个I/O中断发生时,表明某个I/O操作已经完成,等待该I/O的任务将从阻塞状态变为就绪状态,此时是立即执行新的就绪任务,还是继续执行刚才被中断的那个任务?
当一个时钟中断发生时,表明一个时钟节拍已经结束,这时可能会唤醒一些延时任务,使它们变为就绪状态;或者当前任务时间片已经用完,从而变成就绪状态。此时需要调度器重新调度。

调度的方式

任务调度的第二个问题是调度的方式。有两种:可抢占调度(preemptive)不可抢占调度(nonpreemptive)
不可抢占方式:如果有一个任务长时间地占用着CPU,系统也不会强制它中止。
可抢占方式:当一个任务正在运行的时候,调度程序可以去打断它, 并安排另外的任务去运行。
实时操作系统大都采用了可抢占的调度方式,使一些比较重要的关键任务能够打断那些不太重要的非关键任务的执行,以确保关键任务的截止时间能够得到满足。

调度的算法

关于任务调度的算法,请参考以下文章:
《嵌入式系统的任务调度算法》
《任务调度算法汇总》

参考资料:《嵌入式系统设计师》第3.3章节 任务管理

0 0
原创粉丝点击