日期:2000年5月18日20:36译者:陈德勇e_mail:[email protected]原作:JoelR.Williams(emlinux的主要设计师,专为网络和通讯设计嵌入式系统,http://www.emlinux.linux)
摘要:Linux系统不仅能够运行于PC平台;然而在嵌入式系统中Linux仍然可以大放光芒。本文描述了嵌入式系统的特色,和如何在嵌入式系统中应用Linux。
计算机用于嵌入式控制设备领域的历史和计算机本身的历史一样久远。最初的用于控制机电式电话交换器的通讯设备中“固态控制程序”就是嵌入式程序。“计算机系统”在当时并不普遍;所以固态程序存放在内存中控制相应的设备。在那种时代,运行控制程序是很先进的思想,而且当时也只能如此而已。
那时的计算机是专为特定的用户设计,特殊的应用程序指令、I/O设备和主要的计算设备集成在一起。微处理器的产生改变了这种局面,价格低廉、结构小巧的CPU和外设连接在总线上形成了比较大的系统。这种硬件架构很稳定,于是在这个基础上,这建立起了通用的软件开发环境和编程模式,且简化了编程,。
软件也在随着硬件的发展而发展;开始只有简单的工具用于编程和调试,而且每一个软件都必须从头编写。程序大都采用宏汇编语言,汇编程序还不很完善,调试是一件很麻烦的事。因此一直到70年代的中期,模块化编写程序和标准化的运行库才逐渐流行起来。在70年代的后期,出现了嵌入式系统的操作系统。它们采用汇编语言编写,而且只能运行在相应的特殊处理器上;处理器过时,则这个操作系统就没有用处了,对新的处理器必须重新编写操作系统的所有代码。C语言出现以来,采用C语言操作系统更有效率了,操作系统的编写有了很大的改观。C语言有很好的稳定性和可移植性,所以今天的许多操作系统都使用C来编写。于是在80年代末,出现了好几个商业的嵌入式操作系统。而且它们已经演化成为今天的主流嵌入式操作系统。比如很有名的、使用者众多的操作系统:Vxwork、pSOS、Neculeus和WindowssCE。
不过很多的嵌入式系统还没有使用操作系统,它们仅仅包含一些控制流程而已。在嵌入式系统相对简单的情况下,这些控制流足以应付。但是,当嵌入式系统的功能复杂后,简单控制逻辑就不够用了,这时你必须使用操作系统。如果不使用操作系统将会使得控制系统逻辑结构复杂混乱,很容易出错。再者,有些嵌入式系统需要接入网络系统,比如宾馆的门锁控制已经需要接入网络,因此就更需要嵌入式的操作系统来支持应用软件。
除了商业化的操作系统外,还有其他的有版权要求的非商业化嵌入式操作系统可以使用。然而今天的Linux系统有着嵌入式操作系统需要的很多特色、突出的优势:适应于多种CPU和多种硬件平台,性能稳定,裁剪性很好,开发和使用都很容易。因此,我们决定在嵌入式系统中使用Linux操作系统。
1.它具有很好的工具,可以跨越ICE等屏障
原来开发嵌入式系统的关键是需要一套好用的开发和调试工具;而且在开发所不同阶段还需要不同的工具。就比如工匠,只有好的工具才能够使工作完成得又好又快。
传统的开发调试工具就是ICE-在线仿真器;它取代目标板的微处理器,给目标程序提供仿真环境,同时可以连接监视器;允许开发者调试和监视程序的运行。尽管这种运行方式会引起一些奇怪的问题,但是它总能够让你明了程序在目标板的工作状态,免除了对底层的软硬件接口的猜测。但是,这种设备价格非常贵。过去,甚至在整个开发期内,开发嵌入式系统主要依靠这些调试工具。可是,我们发现,一旦软硬件能够正常支持串口的运行时,我们可以使用其他的调试办法。现代的嵌入式系统采用相当成熟的微处理器。因此很容易使得串口工作。串口连接成功,可以进行很多的开发调试。所以我们不用ICE也可以很好地开始开发和调试工作了,同时还降低开发费用。
Linux利用GNU项目的C编译器来编译程序,使用gdb源程序级调试器来调试程序。它们提供了合适的手段来使你能够开发嵌入式的Linux系统。为了开发基于Linux的嵌入式系统,可以按以下方法进行:
向串口输出提示字符串,例如“helloword”或“Waston,comehereIneedyou!”等,然后通过串口,指挥gdb开始工作。以这种方式和另外一台运行gdb程序的Linux主机系统“交谈”,通过串口,你可以很方便地让gdb调试目标程序。通过串口和gdb通讯,可以进行C源程序级的调试。甚至你还可以以串口把其他的程序下装到RAM或flash存储器。通过串口,使用gdb可以使得软硬件的初始化代码继续运行到核心全部启动。
一旦核心在运行了,你就可以使用其他的更好的调试工具,象Kgdb等,如果连接了网络,你也可以让网络工作起来。同时你就可以用GUI的xgdb来调试应用程序。
2.满足实时性时要求
细细分析起来,大多数系统并不需要严格的实时性。而嵌入式系统也经常被误解为就是实时性系统。其实,多数嵌入式系统并不需要实时性,而且实时性本身是个相对的概念绝对的实时性是指对需要的服务以限定的方式和在限定时间内提供,比如在微秒级内响应。这种硬实时性功能只是针对特殊的设备而言,例如数字信号处理等。而这些要求使用特殊的硬件如FIFO、DMA和其他特殊设计的硬件也可以满足。
有些设计者不能够准确地分析出系统真正实时需求,很多情况下对实时的需求在1-5毫秒内响应就可以;大部分情况下,软实时响应足以满足要求:WINDOWSS的98Crashed_Yet在98%的时间内可以在4每秒内响应,如果时间是20秒,则总会响应。那些软实时性容易满足。需要考虑的因素包括:上下文转换时间、中断延迟、任务的优先级和任务调度方式。上下文转换时间曾经是实时性分析的重点,但是因为CPU速度大幅度提高,它不再是关键问题。
现在,严格要求的实时性任务的决定因素是中断例程本身和内核中的其他驱动程序有关;而响应延迟时间主要受中断的优先级和其他进程会暂时地关闭中断响应的影响。因此管理和驱动中断的机制必须保证实时要求。
对于Intelx86处理器,实时扩充可以在Linux系统中很容易进行,RT-Linux就是很好的例子(见http://www.rtlinux.org/)。它主要是把Linux的任务作为自己的一个任务,因此实时性要求很高的任务不受非实时的Linux的干扰,可以得到满足。另外还提供了实时任务和Linux的基本核心和其他任务间的接口,这些接口是不需要很强的实时性。这种架构为其他的嵌入式系统提供了一个参考。关键因素就是实时性的代码和非实时代码分开设计,而且实时应用程序的处理方式和其他程序的处理方式差不多。
3.适合嵌入式系统的Linux有一种观点认为:
用户不必直接干预机器的运行,即没有用户接口的应用系统是嵌入式系统。其他的比如电梯控制系统应该是嵌入式系统,但是它需要人为控制。连接网络需要监视和控制网络系统运行的系统,仍然是嵌入式系统;因此应该根据系统的主要目的和功能来判定是否是嵌入式系统。
最小的嵌入式Linux系统必须包括以下主要的要素:
1) 启动程序;
2) 融合了内存管理、进程管理和时间分批服务的核心;
3) 初始化程序。为了达到要求,而且为了保持最小系统,需要添加以下要素:
a. 硬件的驱动程序;
b. 必须的应用程序。根据其他需要,你可能增加以下功能:
a) 文件管理系统(在ROM或RAM中);
b) TCP/IP通讯协议;
c) 磁盘。
4.选择合适的硬件平台选择硬件平台是一件很麻烦的事,受很多因素影响,比如公司的指导原则、个人偏见、过去产品的影响和消息不灵通等。费用是考虑的主要因素。提醒你考虑价格时不要只注意CPU的价钱,要对整个系统进行考虑。但是如果你是系统设计师,你必须把软件的实时性和硬件结合起来考虑。首先考虑需要多快的CPU,然后把选择三倍化的结果;因为在实际中应用程序会使用一些cache(缓冲),所以理论上速度很快的CPU的实际速度会降低。其次考虑选择多快的BUS(总线);如果可以包括其他的总线,比如PCI,就加上它。因为有时即使使用DMA方式传输,也会使快速CPU变得象蜗牛一般。选用集成外设的CPU比较好,而且还可选用现成的外设驱动程序,大大减少调试工作,实际上有些芯片集成的功能并不是我们所需要的,所以也不要认为凡是集成的都是好东西。
5.压缩制作Linux系统对Linux的通常感觉是大,似乎不适合于嵌入式系统。事实并非如此。因为典型的发行Linux集成了很多桌面PC机需要而嵌入式系统并不需要的功能。首先,我们可以把核心(kernel)从其他任务中分离出来。标准的Linux核心总是贮留在内存中;当需要应用程序时,它把需要的程序从磁盘调入内存运行。程序运行完毕,内存清空,卸载程序。在嵌入式系统中,经常没有磁盘。目前有两种办法来处理没有磁盘的情况。对于比较简单的系统,核心(kernel)和应用程序同时贮留在内存,当系统启动时,就启动应用程序。这种方式和以前的嵌入式系统一样工作。Linux系统也支持这种方式。第二种方式是,考虑到Linux有load(装载)和unload(卸载)程序的能力,嵌入式系统也可以使用这一特点,来节约内存。假如有一个典型的嵌入式系统:包括8到16M的FlashMemory和8到16M的RAM;可以在FlashMemory上建立文件系统,使用Flash的驱动程序来驱动FlashMemory上文件系统工作。另外,也可以使用FlashDidsk,其中有一个例子是M-system的DiskOnChip,它可以支持达160M的FlashDisk。把使用的应用程序文件存放在Flash文件系统上,根据需要调入程序。这种动态装入方法有很多优点:(1)因为在Linux中有一些应用程序只是在初始化时使用一次,然后就没有用处了,另外它们运行方式是一个接一个,顺序进行的。可以允许初始化程序的代码在使用完毕后被废弃,不必永远存放在内存。因此相同内存可以运行不同的程序。这样很节省内存的。(2)软件更新比较容易;可以在系统运行的情况下更新应用程序和驱动程序。
6.如何处理虚拟内存标准的Linux还有一个特点是使用虚拟内存,程序过大,可以交换到虚拟存储器上。这是一个神奇的功能,它使得程序有很大的运行空间。然而,在嵌入式系统中,这个功能似乎没有用武之地,因为没有磁盘。这个功能对于嵌入式系统,特别要求实时性很强的系统来说的确不那么重要,因为这个机制会浪花费时间,所以,嵌入式系统的应用程序还是在固定的地方运行比较好。不过提醒你重注意,考虑到一些CPU有这方面的特点,建议保留虚拟存储器的代码。不仅因为剔除这部分代码很费事,如果剔除相关代码,还容易造成其他问题。更主要的是这保留了这部分功能,能够使得不同进程使用相同代码。如果没有了这个功能,每个程序都需要自己的运行库,在内存中就会有库的很多拷贝。其实只需把交换空间的长度设置为零,就可以关闭虚拟内存的页面换入和换出功能。对一些CPU,虚拟存储器的功能提供内存管理,防止不同程序占用相同的地址空间。而在嵌入式系统中,使用简单、绝对的地址空间,因此这种功能也不会起作用。不过这到提供了防止误写以至于使系统崩溃的功能。很多嵌入式系统习惯使用“全局变量”,让进程共享数据。在Linux系统中提供共享内存方法让进程共享数据信息。在RT-Linux中使用FIFO进行信息交换。
7.处理文件系统很多嵌入式系统没有磁盘和文件系统;Linux也可以在没有磁盘的系统上运行。正如上面提到的,应用程序可以和核心一起编译,在启动时一起装入运行。这适应于简单系统,但不具有灵活性。其实,许多商业的嵌入式系统都提供文件系统的选择。大都是特殊的文件系统或者兼容MS-DOS文件系统。Linux提供包括MS-DOS等许多选择。其他的文件系统具有更好的性能。Linux还具有许多实时商业操作系统所不具备的检查和修复文件系统的功能。这种功能对于通过网络更新的系统尤为重要。Linux的文件系统可以建立在传统的磁盘上、FlashMemory、或其他载体。甚至可以用RAM磁盘存放临时文件。有些系统中包含了廉价的CD-ROM,它比FlashMemory更便宜,更新升级更容易。Linux系统可以从CD-ROM中启动以及运行程序。在网络化的嵌入式系统,Linux支持NFS(网络文件系统)。于是,你可以使用很多网络功能。首先,可以通过网络来启动应用程序。因为通过服务器来启动应用程序,所以是进行软件更新的最好解决办法。其次,在运行过程中,可以很方便地导入和导出数据、状态设置和状态信息等。这个功能很适合用于远程监视和控制应用系统。例如,在RAM中建立磁盘,保存各种需要的重要数据,远程系统登录到此RAM文件系统,读取数据,然后在操作者的机器上用图形界面显示运行状态,起到很好的监视效果。
8.设置启动-LILO和BIOS当微机启动时,它运行预定地址的代码,那地址通常是在只读存储区,存放有启动代码。在PC中,即BIOS,它执行底层的CPU初始化工作和初始化设置其他硬件。BIOS确认哪个硬盘存放操作系统,拷贝操作系统到RAM中,然后运行操作系统。同样,Linux在PC上运行,依靠PC的BIOS来设置硬件、启动OS。在嵌入式系统中,通常没有BIOS,因此,需要提供等价的启动代码。嵌入式系统并不需要象PC那样灵活的BIOS启动程序,它初始化的硬件比较单一。这段代码其实很简单,只是把一些很重要,而且还要特殊的写入顺序要求的数据写入硬件的寄存器。另外必须具备的功能有内存检测,点亮LED,检测其他很重要的硬件。这些代码的针对性很强,不需要很好的移植性。所以不同的硬件环境需要不同的启动代码。为了进行测试,可以使用ICE(在线仿真器)或其他的设备来调试这部分代码。这部分代码总是运行在Flash或EPROM等芯片上,所以,需要把它们写入这些芯片。如何写,当然因硬件的不同而不同了。一个最为普通的方法是使用EPROM或Flash烧录器,把程序烧录在芯片,然后把芯片插入板上。另外的方法是通过JTAG接口进行。
9.嵌入式的Linux同样健壮可靠和其他的运行于PC的系统相比,Linux是最可靠和最稳定的操作系统。而嵌入式的核心也是如此的。Linux的核心移植到新的微处理器上,基本不用什么修改。因此Linux可以使用许多计算机板。外设的驱动程序也多如牛毛,而且比其他的都稳定好用。但是,如果不是PC平台环境,那么你必需为特殊硬件编写驱动程序。对于各种硬件的相似驱动程序市面上随处可见,所以,你可以DOWN下来修改而成,所以安装新的或特殊驱动器、网卡、串口、并口就不困难了。不过,我还是建议你在身边放一本Kernel的书比较好,以备查找。在我的经验中,我觉得使用Linux的错误大都是对系统的了解不准确所至。况且,Linux的源代码随处可得、注释丰富、文档齐全,你完全可能自己去解决问题。
10.结束语嵌入式的Linux系统也有缺点。和某些商业操作系统一样,占用较大的内存。当然可以去掉部分无用的功能来减小使用的内存,但是,如果不仔细,将引起新的问题。有些Linux的应用程序需要虚拟内存,而嵌入式系统中并没有或不需要虚拟内存,所以,并非所有的Linux应用程序可以在嵌入式系统运行。核心的调试工具并非完尽人意,虽然可以使用kgdb,不过我们更多的是使用print语句来帮助调试。在应用于嵌入式系统的主要问题是:Linux本身具有很大的灵活性,而嵌入式系统不具有灵活性,它们主要针对特殊的问题。这是问题的关键。总之,Linux用于开发嵌入式系统的应用软件是可能的和可行的。
摘自:http://www.pocketix.com