3.3 嵌入式操作系统组成要素及概念
嵌入式操作系统虽然各有不同,但是基本来讲,都是针对各类硬件资源管理的,包括针对分享MCU的任务管理、消息机制、同步机制等,针对接口硬件的中断处理,针对内存的内存管理、文件管理,针对网络的网络支持、网络管理等。在深入学习嵌入式操作系统之前,先介绍嵌入式操作系统组成要素及其概念,如任务、实时、内核、调度等。
1.任务
任务是一个抽象的概念,进程和线程都只是任务的一个特例。简单而言,嵌入式操作系统中的任务是一段无限循环的代码,在这段代码执行的过程中有相应的堆栈、内存的分配。
每种特定的嵌入式操作系统都有自己的描述单位。例如,Windows CE中以进程为基本单位来描述资源,每个进程一旦运行,操作系统要为其开辟相应的内存空间,供其进行临时数据存储等操作。线程则被MCU实际调度,是调度的实体。一个进程创建之后,同时将创建一个主线程。可以在主线程中创建该进程的其他线程。进程可以被视为线程的容器。一个线程默认的栈大小为64KB,也可以在创建线程的时候自定义栈的大小。同一个进程中,一个线程分配的内存,可以被其他线程所访问。不同进程中的线程如要互相访问,则需要通过进程间通信来处理。在Symbian操作系统中,每个进程都有一个或多个线程。线程是执行的基本单位。Linux中线程和进程则更加含混,都使用任务这个结构来描述。
比较线程和进程,总的来说,进程的描述粒度较大,涉及内存空间的划分,不涉及具体微处理器的寄存器等,离硬件的距离比线程远。线程在运行时涉及具体寄存器等保存和上下文环境切换,由微处理器进行调度,与微处理器的资源联系紧密。图3.7(a)是单线程进程的内存运行模式,图3.7(b)是多线程进程的内存运行模式。在图中,每个线程都拥有自己的寄存器和堆栈,而每个进程只拥有自己的代码、数据和文件。
图3.7 单线程进程和多线程进程
2.实时
实时性是一般嵌入式操作系统有别于其他通用操作系统的一个特点。这里的实时性是指系统的正确性不仅取决于逻辑的运算结果正确,而且取决于结果传递的时间必须在时限要求内。能支持这样的实时性的操作系统称为实时操作系统,换句话说就是需要能为不确定发生时间的外部事件做出时间确定的反应。好的实时嵌入式操作系统必须在所有情况下运行都能获得确定的结果。这样的操作系统小到10KB,大到100KB。时限必须满足的限制称为硬实时。如果允许偶尔地打破时限,并在这种不正常情况下还能恢复到常态即满足时限状态,则称为软实时。
3.多任务
多任务是实现实时性的一个好方法。如果是在一个处理器上实现多任务,则是一种多任务的伪同步方式。此时,多任务分时使用处理器,在一段时间内看起来多任务同时使用处理器,也称为多任务并行。这种方式需要额外的控制,如时间的划分,当前运行任务的退出,选取任务进入处理器进行处理等。如果是多处理器,在同一时刻,多个任务可以运行在多个处理器上,但是需要额外的控制机制来保证任务运行整体的确定性。多处理器上的多任务目前仍在研究阶段。
对于单处理器的这种多任务同步的实时性,需要考虑任务从微处理器换入、换出的时间。而进程的概念比较大,这种换入、换出所涉及的内容太多,无法满足实时的要求。为此,在多任务的系统中常常使用线程作为基本单元。这也就是现在对于实时系统只提及任务或者线程的原因。
4.任务状态及转化
嵌入式操作系统中任何任务一般都处于以下三种状态(见图3.8)。
运行态(Running):此任务正占有微处理器并正在获得执行。在单处理器系统中,某一个时刻仅有一个任务在运行。
就绪态(Ready):此任务已获得所有可拥有处理器来运行的条件,而此时某个其他任务正占有微处理器,此任务必须等着微处理器空闲。
阻塞态(Blocked):此任务还不具备一些条件,此时就算处理器分给该任务也无法运行。任务在此状态下意味着在等待一些外部事件,如在等网络传来数据,而数据还没有到达的情况。
图3.8 任务状态图
5.内核
嵌入式操作系统中有一部分功能是所有操作系统都有并构成操作系统的核心部分,纵使如何裁剪系统,也无法去掉的,称为内核。一般内核可以按功能分为几块:任务调度、消息处理、内存管理、中断处理、时间管理。
6.调度
调度是嵌入式操作系统的灵魂。所谓调度包括两个大概念和一个小概念。第一个大概念是指如何分配微处理器给就绪的任务的换入策略,第二个大概念是指正在占有微处理器的任务的换出策略。小概念是指当有正在执行的任务被中断换出时,中断结束后是回到刚才的任务还是重新选择,也就是抢占还是不抢占的调度问题。
在就绪状态等待微处理器的任务不止一个,到底谁能占有微处理器而进入处理状态,是需要策略的。最简单的换入策略如先进先出,谁先到达就绪状态,就先分微处理器给谁。但是在嵌入式操作系统中一般采用基于优先级分配的策略。所谓优先级分配策略就是每个任务根据重要程度分配其优先级别,哪个就绪任务的优先级高,哪个任务就可以占有微处理器。
正在执行的任务何时换出?任务执行完自然会换出。但是一般任务都是一段循环代码,执行起来会进入反复操作,为此给每个任务分配时间,又称分配的时间片。该任务的处理时间用完了,也就是该换出的时候了。另外按照优先级的思路,如果有比正在运行的任务优先级更高的任务到了就绪状态,正在运行的任务也该让出微处理器,此时也需要换出。
特殊的是中断,中断是来自硬件的信号,必须及时处理。一般中断到达后,当前在运行的任务需要换出,让出处理器给中断使用。中断处理后返回刚才被中断的任务,称为非抢占式调度。中断处理后所有任务重新按换入策略选择,称为抢占式调度。