实时操作系统应用杂谈(一)
目前,越来越多的嵌入式系统中都使用了操作系统。就本人而言,当前开发的产品,几乎全部带有操作系统。所用过的系统包括:RTX51(Keil-C51)、uC/OS-II(ARM)、RLRTX(Keil-ARM)和DSPBIOS(TiDSP)。这些都是实时操作系统(RTOS)。关于RTOS应用的书籍不少,但涉及如何写好程序的少之又少。的确,写出好的程序需要长期的经验,但经验又是个不太好表述的东西。希望我写的这些文字能尽量讲明白我对编程的理解。之后所述的这些文章都是基于我用所过的系统,其他系统可能有所出入。望同僚们评判。
一、关于“任务”
RTOS中的任务,有时也习惯称作“线程”。这可以同PC程序中的线程相对应,比较好理解。
通常,书中会提到:在设计一个较为复杂的应用程序时,把一个大型任务分解成多个小任务,然后通过运行这些小任务,最终达到完成大任务的目的,这种做法也可使应用程序的维护变得容易起来。
到底怎么细分任务呢?我谈谈自己的看法。
1。系统应用角度
这是从嵌入式系统的实际应用(功能)角度来分析任务的拆分。
一个系统包含好多“应用功能”,比方说:人机界面的操作、通过通讯口传输数据、对离散输入的自动处理等等。这些功能相对比较独立、其相互的关联较少,因此可以当作独立的任务来处理。
对某些同类的功能只写一个任务程序,运行时再建立多个同类任务,可以极大的减少程序量,同时方便维护。举个例子:我设计过的一个“定量包装秤”的控制系统。一个秤有4到16个称量通道,每个通道包含进料-称重-出料的控制流程。我编写了2个任务,一个是通道控制任务,负责通道的运行;一个是通道管理任务,负责按需建立多个通道控制任务、协调通道控制任务之间的运行。
对于数量不明的应用功能,也应按照上述的方法设计,比如支持多线程的网络通讯。
另外,某些具有阻塞性的功能,比如通讯功能,最好建立独立的任务。
2。系统结构角度
这是从嵌入式系统的部件结构角度来分析任务的拆分。这是相对细化的任务拆分。
当系统中的某些部件的运行比较有独立性,和其他部件的关联比较少时,比如:按键的扫描检测任务、USBHost处理任务、音频输出处理任务等等。这些功能是基于某些硬件的操作,具有周期性、连续性的特点,可以建立独立的任务。
3。“面向对象的设计方法”
这里所讲的,并非完全使用“面向对象的设计方法”来设计程序,只是希望可以应用一些其中的一些理念。比如“对象”、“通过消息的通信”等等。将某一些属性、功能、操作的集合体可以看作一个“对象”,通过“消息”来协调“对象”。前面的“定量包装秤”的例子也可以说明这一点。将通道看作一个“类”,由通道管理任务建立各个通道的实例(通道对象),即初始化每个通道的运行参数(属性),建立通道工作任务。每个通道运行的状况,通过“消息”传递给管理任务进行协调。
在应用嵌入式实时操作系统时,会用到众多的、以前只在PC程序设计中遇见的“消息”、“事件”、“管道”等概念,特别是“消息”、“事件”是应用RTOS不可或缺的部分。以后还会详细讲到。
涉及到任务的另一个问题是任务的优先级。任务优先级的多少各个操作系统都不一样,有16级的、255级的。一般由0开始。值得注意的是:有些操作系统将“0”定义为最高优先级,有些则将其定义为最低优先级。对于非“占先”型的、或者关闭“占先”功能的操作系统来说,优先级作用不大,其一般使用“循环调度”来分配任务的运行。
具有“占先”性的操作系统,配置优先级别有时是个头痛的问题,做不好极大影响整体运行性能。通常,书籍上会提到:任务越重要,指定给它的优先级就越高。但在实际的设计中,会感觉什么任务都重要,孰重孰轻自己也说不清。
下面说说我的经验:
1。需要实时性高的任务重要。
这里的“实时”是相对而言的。最实时的处理一般都是在中断操作中进行,次一级的实时处理放在软中断,在后的就是在任务中的处理程序。比如:一个扫描键盘的任务每100ms扫描一次按键,另一个读取时间的任务每1秒钟读取一次时钟,这时扫描键盘任务优先级应该较高。
2。越是底层的任务程序,优先级越高。
程序设计中,某些任务是应用层的任务,某些任务则负责底层驱动。这时负责底层驱动的任务优先级要高。比如,扫描键盘的任务和执行数据统计的任务相比,扫描键盘任务优先级应该较高。
3。占用较多资源的任务,优先级越高。
这里的“资源”是指某些硬件,比如说I2C总线、闪存读写操作等等。另外,涉及到任务共享资源的状况时,有时会出现“优先级反转”问题,这时需要在任务中动态调整优先级。
4。执行时间越短的任务,优先级越高。
用户230766 2009-11-17 20:09
用户230766 2009-11-6 13:44