⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄

📁 嵌入式系统
💻
📖 第 1 页 / 共 3 页
字号:
      <P>使用Linux, 
      出现了另外一种方式.既然Linux有装载和卸载程序的能力,一个嵌入式系统可以利用这一点以节省RAM.考虑一个比较典型的系统:有大约8兆到16兆的闪存和8兆RAM;那么闪存可以被用作文件系统.用闪存驱动程序作为从闪存到文件系统的界面.作为一种选择,也可以用一个闪存磁盘.这是用闪存来摆脱系统对一个磁盘的需求(依赖).使用这种方式的一个例子是M-System(http://www.m-systems.com/)中的DiskOnChip技术,它可以支持160MB.所有应用程序以文件的形式被存放在闪存文件系统中并在必要的时候被装载到内存中;这种"用到时才装载"的能力是一个很强大的特征,从而可以很容易地具有(支持)以下各种能力:</P>
      <P>1: 
      允许系统启动后抛弃(释放)那些初始化代码(空间).典型地,Linux用到很多运行在内核外部的工具性程序(utilities).它们通常仅在系统初始化期间运行一次,以后将再也用不到.而且,它们以互斥的方式,一个接一个地依序运行.这样,随着系统的启动,一段内存可以被反复地使用:"以页调入"的方式运载每一个程序.这可以很好地节省内存,特别是处理像网络栈那样的对象时,因为这些对象一经配置便永不更变.</P>
      <P>2: 
      如果Linux之支持可动态装卸模块的特征被包含在内核之中,不仅各种应用程序,驱动程序也可被动态装卸.这样,系统能够检查硬件环境并有选择性地仅仅装载那些适应当前硬件环境的软件.这可以取消(降低)让一个程序以占用更多闪存的代价处理众多硬件变数的复杂性.</P>
      <P>3: 系统的升级更加标准化(模块化),你可以常常在系统运行过程中升级一些应用和驱动程序.</P>
      <P>4: 配置信息和运行时间参数可作为数据文件存放在闪存中.</P>
      <H3>无虚拟内存交换</H3>
      <P>另外一个Linux的特性就是虚拟内存交换。这一特性将应用程序的编写引入歧途,应用程序的内存需求量可以无限制地上升,因为操作系统在磁盘中提供了交换空间。而在一个无盘的嵌入式系统中,这种特性就用不上了。</P>
      <P>如此强大的功能,在嵌入式系统中竟无用武之地。事实上,在一个严格的实时系统中你可能并不需要这种特性,因为它会导致定时功能的失控。如同其它的嵌入式系统一样,软件的设计必须很紧凑,以适应较小的物理内存。</P>
      <P>注意,这取决于你的CPU体系,比较明智的做法是保留Linux的这段代码,毕竟,砍掉这些代码,还是要付出一些工作量的。但是,这些代码依然有保留的理由。因为它们能够支持代码共享,多个进程可以共享某一软件的同一拷贝。如果无此功能,那么,每一个程序都必须拥有库程序的独立拷贝,例如:printf 
      。</P>
      <P>将交换空间大小简单地置为零,就可以关掉系统虚拟内存的分页交换机制了。当你的程序要求内存大于实际的内存时,系统的表现就如同交换空间溢出时一样:你的程序不会被加载,或者,当要求过多内存时,malloc 
      调用失败。</P>
      <P>在许多的CPU体系中,虚存机制提供的内存管理可使进程的地址空间相互隔离。一般在嵌入式系统中不是这样,地址空间是简单的,平坦的情况。Linux的虚存机制使出错的进程不致影响整个系统。在许多嵌入式系统中,因为效率原因而设置的全局数据,同时被几个进程所共享,这在Linux中也存在,那就是内存共享,它可以经过设置,使某一段内存成为共享内存。</P>
      <H3>文件系统</H3>
      <P>许多嵌入式系统不存在一个磁盘或者一个文件系统。没有它们中的任何一个,Linux也可以运行。正如前面提到的那样,应用任务可以随同内核一起被编译并在启动时作为一个映像被加载.对简单系统来说,这已经胜任.不过,它却缺少前面描述到的各种灵活性.</P>
      <P>事实上,如果你观察过许多商业性嵌入式系统,你会发现他们把文件系统作为可选项来提供.大部分要么是一个私人拥有的(专门)文件系统,要么是一个与MS-DOS兼容的文件系统.Linux不但支持许多其它文件系统也支持MS-DOS兼容的文件系统,通常推荐使用除MS-DOS兼容文件系统以外的其它文件系统,因为它们有较优的健壮性和容错性.Linux也有检查和修复工具(不过商业卖主一般不提供),这对从网络上进行更新的闪存系统尤为重要.如果系统在升级中断电,可能导致系统无法再用.一个修复工具通常可以排解此类问题.</P>
      <P>文件系统可以放在一个传统磁盘驱动中,或闪存中,或任何可用的其它介质中.同样,一个小的RAM 
      disk常常可以很好地存放暂时性文件(易失性文件).闪存被分隔成很多小块(并被组织起来).它们中可能有一个引导块,它存放了CPU上电后运行的第一个软件.可能存放的就是Linux的引导程序.余下的闪存块可以被用作文件系统.Linux的内核可以被引导程序从闪存中拷贝到RAM中;或者,作为另一种选择,可以把内核放在闪存的一个独立区中并从那里直接运行.</P>
      <P>对一些系统来说,另一可行的选择是包含一个廉价的CD-ROM驱动.它可能比闪存还要便宜.并且借助更换CD-ROM盘片就可很容易地得到升级.通过这种方法,Linux只需从CD-ROM启动并可以像对一个硬盘那样从该CD-ROM中获得所有用到的程序.</P>
      <P>最后,对于网络上的嵌入式系统(有网络支持的嵌入式系统),Linux支持NFS(Network File 
      System).这一着打开了在一个网络支持系统中实现各种增值特征的通道.首先它允许通过网络加载各种应用程序.由于用在每一个嵌入式系统上的软件可以从一个公用的服务器上加载,这在控制软件的修订或升级中是很重要的.在系统运行的过程中,导入和导出数据,配置,状态信息的一个备份也很有用.对用户监控而言,这是一个非常强大的特征;举例来说,一个嵌入式系统可能装配了一个RAM 
      disk,它包含着与系统当前状态的更新维持一致的(状态)文件.那么别的嵌入式系统仅需通过网络把这个RAM 
      disk作为远程磁盘mount过来便可以访问那些位于远端RAM 
      disk中的状态文件.这也允许在另一台机器上的WEB服务器借助简单的CGI脚本来访问那些状态信息.运行在其他机器上的应用程序包能够很容易地访问这些数据.对更复杂的监控,像MatLab(http://www.mathworks.com/products/matlab/)这样的一个应用程序包能很容易地用图形化来显示在一个系统操作者的PC或工作站上的系统操作.</P>
      <H3>引导内核--当没有LILO或BIOS时</H3>
      <P>当一个微处理器最初启动时,它首先执行在一个预定地址处的指令.通常这个位置是只读内存,其中存放着系统初始化或引导程序.在PC中,它就是BIOS.这些程序要执行低级的CPU初始化并配置其他硬件.BIOS接着判断出哪一个磁盘包含有操作系统,再把OS拷贝到RAM中,并把控制权交给OS.实际上,整个过程远非这么简单,不过对我们的理解已经足够.运行在PC上的Linux系统依赖于该PC的BIOS来提供这些配置和OS加载功能.</P>
      <P>在一个嵌入式系统里,常常没有上述的BIOS;这样,你就需要去提供等价的启动代码.还好,一个嵌入式系统的BIOS并不需要像PC 
      BIOS引导程序那样有那么多的灵活性,因为它通常仅需处理一种硬件配置方案.这些代码比较简单但也另人厌烦.它是一些把特定的数写入指定硬件寄存器的指令序列.不过这是很关键的代码,因为这些数值必须要符合你的硬件并且要按特定顺序来完成.在大多数情况下,(这些代码中)有一个最小化的加电自检模块用以检查内存,让一些LED闪现一下,也可能探测一些其它让Linux 
      OS启动和运行的必要硬件.这些启动代码是高度硬件专用性的,因而,不具移植性.</P>
      <P>有幸的是,大多数系统为核心微处理器和内存使用了食谱式的硬件设计.典型地,芯片制造商有一个可供设计参考的演示板--新设计多少可以从中直接拷贝一些.对这些食谱式的设计,经常有现成的启动代码可用,而且可以很容易地被修改以适应你的需要.很少(会遇到)有需要从头开始编写的启动代码.</P>
      <P>为了测试你的(启动)代码,你可以使用一个包含它自己的仿真内存的电子仿真器(in-circuit 
      emulator),这里的仿真内存用以替换目标内存.你把待测代码加载到仿真器中并通过仿真器调试它.如果没有可用的仿真器,也可以跳过这一步,不过需要一个较长的调试周期.</P>
      <P>这些代码最终要从非易失性存储器中运行,通常是用闪存或EPROM芯片,你要想办法把这些代码放进前述芯片中,放入的具体方法依赖于"目标"硬件和工具.一个常见的方法是把闪存或EPROM芯片插入到一个EPROM或闪存"烧炉"中.这种方法将把你的程序"烧入"(存入)芯片中.然后,把芯片插入到你目标板上的一个插槽中,打开电源.这种方法要求在板子上具有插槽化(socketed)部分;然而,有些设备包格式(结构)不允许被插槽化(socketed).</P>
      <P>另一种办法是通过一个JTAG接口.一些芯片包含一个JTAG接口,从而可以对芯片编程.这是一种最简便的办法.芯片可以被永久地焊接到板子上.一段电缆从板子上的JTAG连接器(通常是一个PC卡)连接着一个JTAG接口.接下来要求在操纵JTAG接口的PC上做一些用户定制性编程.在仅需较少运行量的产品中,也可以使用这种方法.</P>
      <H3>健壮性---比政客的承诺还可靠</H3>
      <P>这是显而易见的,作为一种选择,Linux已被普遍地认为能够在PC平台上可靠地,稳定地运行。嵌入式内核自身有多稳定?对于大多数微处理器来说,Linux是很好用的。将Linux移植到新的微处理器体系也是非常迅捷的。一般是将其移植到一种新型的目标板,这种新型的目标板包含有独特的外设,当然还有CPU.</P>
      <P>幸运的是,大部分的内核代码都是相同的,因为它们与微处理器无关,所以,移植的工作都集中在那些不同的部分,通常是一些存储器管理及中断处理程序。一旦完成,它们往往是非常稳定。如同前面谈到的,引导的过程非常依赖于硬件的变化而变化,所以,一定要周密地计划一番。</P>
      <P>设备驱动程序虽然变化多端,但其中一些已相当稳定。同时,你的选择也不算太多,一旦离开PC平台,那就只有自己去写了。所幸的是,在我们周围已有许多既有的设备驱动程序,你总能找到一个近似的,而去修改它。驱动程序的接口是明确定义的。大多数驱动程序之间都是相似的,所以,移植一个磁盘,网络,串行口驱动程序,从一个设备到另一种,经常不是太难。我发现大多数的驱动程序都写的很好,并很好理解,而难题反而是在我手上的那本讲解内核结构的书。</P>
      <P>就我个人的经验而言,Linux与我曾经使用过的那些顶顶大名的商业操作系统一样稳定。总的来说,关于这些操作系统(包括Linux)的问题都源于对系统工作策略的误解,而不是纯代码bug或基本设计错误。大量的操作系统的bug故事,在这里没有必要再重提。而Linux的优点,就在于其源码是公开的,并有很好的注释和完整的文档说明,从而,你也就拥有了控制与解决一切问题的能力基础。</P>
      <P>即内核与驱动程序之后,还有一点:如果一个系统中有一只硬盘,那么,系统的可靠性可能会成为问题。我们拥有两年的经验和时间,都沉浸在有盘嵌入式系统中。这些系统从不关机,电源有几次被意外地断掉,可是,EXT2文件系统表现得很好。标准的Linux初始化脚本运行了fsck程序。这个程序做了一个漂亮的检查与清理不正常节点的工作。还有一处英明之举,也是一处较大的变动,我们将update程序由30秒执行一次,调整为5或10秒执行一次。这使得磁盘高速缓存中的数据能较频繁地写回到磁盘里,从而,降低了丢失数据的可能性。</P>
      <H3>没有万能钥匙</H3>
      <P>嵌入式Linux当然有它的不足。比如,它很占内存,尽管不比一些商业竞争者的情况更坏。但可以通过消减一些不必要的功能来改善,也有可能得不偿失,因为很可能会产生比较严重的bug。</P>
      <P>大多数Linux应用程序都会使用虚拟内存交换,这在很多嵌入式系统中是一种非确定因素,所以,不要假定任何一个无盘嵌入式系统能够运行什么Linux应用程序。</P>
      <P>低等级的,内核级的调试工具仍然不是很好使。kgdb会使人感到很不适应,你常要reboot。很不幸,调试仍然是以打印语句为主。</P>
      <P>对于我来说最严重的问题是心理作用。Linux是一种极具适用性的操作系统。可是,嵌入式系统在通常情况下是不具备这种性质的;它们是对于特定的用途,进行过仔细优化了。但Linux的这种适用性倾向,保持了系统的通用性和多变性,同时也是一个奢侈的目标,付出的代价很高,需要增添许多额外的工作,会有许多附加的程序产生,从而增加了软件包的体积,有时还会以降低性能为代价。举一个常提到的例子--配置程序:在一个网络接口上配置IP地址,一般是由启动脚本中的ifconfig完成的。这是一个大小约28K左右程序,其实只用几行代码就可以完成它的工作:它负责根据配置文件中的内容初始化一些相应的数据结构。事情就是这样:当一切成为一件合理的事情去做时,你不这样做,又能怎样呢?不然"软件"意义又何在呢。</P>
      <H3>结束语</H3>
      <P>在嵌入式系统中使用Linux是可能的,并且已经成功了。它可以可靠地工作。从此,我们就在开发的成本上有了第二种选择。</P>
      <CENTER></CENTER>
      <P align=left><FONT size=2>日期:2000-10-13</FONT> </P>
      <P align=center><INPUT onclick=javascript:window.close() type=button value=关闭窗口></P>
      <CENTER>
      <P> </P></CENTER></TD></TR></TBODY></TABLE></DIV></CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -