嵌入式系统
维库,知识与思想的自由文库
|
個人行動數位助理(Personal digital assistants )及手持式電腦(handheld computers)由於它們在硬體上設計的特性,即使在軟體上的擴充性比其他裝置來得好,但普遍被認為是嵌入式裝置。但是這個定義也逐漸模糊。舉例來說,OQO Model 2被引進了Windows XP作業系統(operating system)上、以及使用像USB port--以上兩種特性皆屬於一般用途電腦,因此嵌入式系統的定義又更模糊了。 嵌入式系统的核心是由一个或几个预先编程好执行少数几项任务的微处理器或者微控制器组成。与通用计算机能够运行用户选择的软件不同,嵌入式系统上的软件通常是暂时不变的;所以经常称为“固件(firmware)”。
[编辑] 嵌入式系统实例
[编辑] 歷史第一个被大家认可的现代嵌入式系统是麻省理工学院仪器研究室的查尔斯·斯塔克·德雷珀开发的阿波罗导航计算机。在两次月球飞行中他们在太空驾驶舱和月球登陆舱都是用了这种惯性制导系统。 在计划刚开始的时候,阿波罗导航计算机被认为是阿波罗计划风险最大的部分。为了减小尺寸和重量而使用的当时最新的单片集成电路加大了这种风险。 第一款大批量生产的嵌入式系统是1961年发布的民兵I导弹上的D-17自动导航控制计算机。它是由独立的晶体管逻辑电路建造的,它带有一个作为主内存的硬盘。当民兵II导弹在1966年开始生产的时候,D-17由第一次使用大量集成电路的更新计算机所替代。这个项目自己就将方块与非门集成电路的价格从每个1000美元降到了每个3美元,使得集成电路的商业应用称为可能。 民兵计算机至关重要的设计特性是它的制导算法能够在项目后期重新编程以获得更高的导弹精度,并且计算机能够测试导弹,从而节省电缆和接头的重量。 由于这些二十世纪六十年代的对于价格没有要求的早期应用,嵌入式系统的价格开始下降,同时处理能力和功能也获得了巨大的增长。这个趋势就是摩尔定律。 第一款微处理器是英特尔4004,它在计算器和其它小型系统中找到了用武之地。但是,它仍然需要外部的内存芯片和其它的外部支持逻辑电路。更加强大的微处理器,如英特尔8080被开发出来用于军事项目和其它用途。 到了二十世纪七十年代末期,8位微处理器已经变得普通,但是它们通常需要外部内存芯片和解码输入输出的逻辑电路。然而,价格在快速下降,更多的应用领域采用小型的嵌入式系统取代当时常见的专门逻辑设计。一些容易见到的应用是仪器和昂贵的设备。 到了二十世纪八十年代中期,许多以前是外部系统的元件被集成到同一个处理器芯片中。这样的结果就是嵌入式系统尺寸和成本的大幅下降。这样的集成电路称为微控制器而不是微处理器,嵌入式系统的大规模应用成为可能。 随着微控制器的价格已经跌落到低于工程师一个小时的工资,嵌入式系统数量和不同厂商提供的嵌入式系统配件数量出现了大爆发。例如,许多新的特殊功能的集成电路开始使用较少插针的串行编程接口而不是传统的并行接口来来连结微控制器。I2C也在这个时候出现。 随着微控制器的价格跌落到1美元以下,使用小型微控制器控制的数字电路取代如分压计和可变电容这样的昂贵模拟元件成为可能。 到了八十年代末期,嵌入式系统已经出现在几乎所有的电子设备中,这个趋势依然在继续。 [编辑] 特性嵌入式系统在最广的意义上说就是计算机系统,它包括除了专门用于通用目的之外的所有计算机。從便攜式的音樂播放器到航天飞机的实时控制子系统都能见到嵌入式系统的应用。 多数商业嵌入式系统都是为了低成本完成任务而设计的。其中绝大多数都有实时系统约束的要求,但并不是所有的嵌入式系统都有这些要求。对于其中一些过程来说它们要很快地完成,而其它一些功能可能并没有严格的时间要求。这些系统通过与特定目的的硬件和根据系统要求配置的软件组合在一起满足实时要求。 很难根据速度或者成本描述嵌入式系统的特点,但是对于大批量生产的系统来说,降低成本通常是设计的首要考虑。嵌入式系经常有很低的性能要求,这样系统硬件就可以简化以降低成本。工程师最小化的实现通常选择刚刚满足所需功能的硬件。 例如,一个卫星电视的数字机顶盒每秒需要处理数十兆连续数据,但是这些数据的绝大部分处理过程是由分析、导引和解码多路数字视频的定制的集成电路完成的。嵌入式CPU“建立”这些处理过程并且显示为机顶盒显示图形菜单等外观。随着嵌入式处理器速度越来越快、价钱越来越低,它们就可以从事更多的高速数据处理。 对于小批量的嵌入式系统来说,经常使用个人计算机通过限制运行的程序或者将操作系统更换为实时操作系统来实现。在这种情况下,用于特殊目的的硬件可以替换成一个或多个高性能的CPU。然而,有些嵌入式系统可能仍然需要高性能的CPU、特殊的硬件和大量的内存以完成所需任务。 对于大批量的嵌入式系统来说,如手持音乐播放器或者蜂窝电话,降低成本是需要主要考虑的问题。这些系统通常有少数几个集成电路、控制所有其它功能的高度集成的CPU和一片内存。在这些系统的设计中每个元件的选择和设计都要有利于降低总体成本。 许多嵌入式系统的软件,尤其是那些没有磁盘驱动器的嵌入式系统的软件也被称为固件。固件是嵌入到硬件设备中的软件,如固化到一个或多个ROM或者闪存IC芯片中。 嵌入式系统上的程序经常运行在有限的硬件资源上:经常没有磁盘、操作系统、键盘和屏幕。软件也可能没有如文件系统这样的部分,即使有文件系统的话通常也是使用日志(journaling)文件系统的闪存驱动器(flash drive)取代旋转的媒体。如果有用户界面的话,那么它就可能是一个小型按键或者液晶显示。 机器中的嵌入式系统通常需要能够经年不断地正确运行,所以它们的软件的开发和测试都要比个人计算机上的软件更为仔细。许多嵌入式系统避免使用可动的部件如磁盘驱动器、开关和按钮等,因为可动部件的可靠性要比如闪存这样的固态部件的可靠性差。 另外,嵌入式系统可能在人无法到达的地方运行,如下到油井钻孔中、发射到外层空间等等,这样嵌入式系统即使在发生灾难性的数据破坏情况下也必须能够自行重新启动。这通常是通过一个名为看門狗計時器的标准电子部件实现的,除非软件周期性地复位这个定时器否则它就会复位计算机。 [编辑] 嵌入式系统设计通常使用微处理器或者微控制器构建嵌入式系统。一些大型的系统或者早期的系统使用通用大型计算机或者小型计算机构建。 [编辑] 用户界面嵌入式系统的用户界面类型非常繁多,所以值得进行特殊说明。 PARC、苹果计算机公司、波音公司和惠普公司的界面设计人员发现界面应该遵循减少用户动作类型这样一个原则。在嵌入式系统中这样一个原则经常与降低成本的要求结合在一起。 在嵌入式系统中广泛采用的一个标准界面是使用两个按钮控制一个选单系统,其中一个按钮允许用户滚动选单条目,另外一个用来选择条目。 选单系统广受欢迎是因为它们本身就说明了自身内容,并且能够通过简单的用户操作选择。 另外一个基本的技巧是减少并简化输出的类型。有些设计在每个接口插头或者错误条件使用状态灯指示哪一部分发生故障。一种廉价的做法是使用两个发光条,另外带有一个打印出来的故障代码表格。用户可以将他所用语言表示的状态贴在标签上。例如,许多小型打印机使用亮灯表示状态,这些状态标示在打印成所需语言的不干胶标签上。在一些市场上,他们可能使用几种这些标签,这样用户就可以选择最适合他们的语言。 另外一个通用的技巧是界面模式要在用户的角度上看起来非常清楚。如果一个界面有不同的模式,它们通常应该可以用明显的方式的方式切换回去或者它们能够自动切换回去。 例如,波音公司的标准的测试界面就是一个按钮和一些亮灯。当按下按钮时,所有的灯就会变亮;当松开按钮时,出现故障的指示灯就不会熄灭。它们的标签都是用基础英语表示的。 设计人员会用不同的颜色表示状态。红色表示“危险”或者一些错误发生导致整个系统故障;黄色表示一些部分可能有故障;绿色表示状态正常或良好。这就类似于街头的红绿灯,大多数人都知道它们的含义。 一些设计保证在用户操作之后马上显示状态的变化。如果机器要做什么动作,通常在7秒内开始并且汇报工作过程。 如果一项设计需要屏幕,设计人员经常选择纯文本方式。优先选用这种方式是因为用户已经有多年识别标记的经验。图形用户接口看起来很漂亮也能完成所有的功能,但是通常它们会增加一年的设计、批准和翻译延期、增加项目一到两个程序员的费用,而这些工作并没有多少实际意义。经常一个过于聪明的图形用户接口因为可能使用用户不熟悉的符号,所以实际上可能会让他们感到困惑。 如果设计需要指示如复印机那样的机器零部件,在实际的机器上它们通常使用数字进行编号,这些编号能在机器外观上看到。 网络界面就是一个远程的屏幕,同其它的用户界面类似。 最成功的屏幕界面之一就是两个选单按钮和一行用户所说语言的文字。它用在寻呼机、中档打印机、网络交换机和其它一些需要用户复杂操作的中档价位的场合。 如果使用的是较大的屏幕,触摸屏和屏幕旁的按钮也可以减少用户操作的类型并且容易控制选单选择。这种系统的优点就是按钮的含义可以随着屏幕而变化,并且选择的过程非常类似于人们自然选择东西的方式。 当使用文字的时候,设计人员就要选择一种或者多种语言。缺省语言通常是目标用户最为常用的语言。许多设计人员使用目标客户群的本地语言以更好地满足他们的需要。 文本通常是由专业人员进行翻译,即使开发人员也说那种语言也是这样。市场销售人员能够告诉国外的销售商说这些翻译都是非常专业的。一个国外的制造商有可能要求最大的销售商审查、更正这些本地语言的翻译以促进产品被本地销售人员接受。 许多权威人士认为可用性测试比任何数量的观点都重要,设计人员推荐可用性要尽早进行测试。一个常用的快速、dirty测试方法是让秘书使用工程师使用奇怪的标志拖动、控制的纸板模型。录制的录像带显示这样做不仅很幽默也很有教育意义,In the tapes, every time the engineer talks, the interface has failed because it would cause a service call. 在许多组织里,用户界面要有一个人要批准,通常这个人是客户、主要的销售商或者直接负责系统销售的人。 [编辑] 平台在嵌入式系统设计中有许多不同的CPU架构,如ARM、MIPS、Coldfire/68k、PowerPC、X86、PIC、Intel 8051、Atmel AVR、Renesas H8、SH、V850、FR-V、M32R、DMCU等。 这与桌面计算机市场有所不同,写这篇文章的2003年为止在那个领域只有少数几家竞争的架构,其中主要是英特尔/AMDx86和用于Apple Macintosh的Apple/Motorola/IBM PowerPC。在桌面计算机领域,随着对于Java接受程度的增长,软件对于特定运行环境的依赖越来越少。 PC/104标准是小型、小批量嵌入式和ruggedized系统设计的基础。这些系统通常使用DOS、Linux、NetBSD或者如QNX、Inferno这样的实时嵌入式操作系统。 大批量生产的嵌入式系统的通常配置是系統單晶片(en:System On Chip),它是一个专用集成电路,CPU是外购的知识产权并且添加到集成电路设计中。一个类似的常用机制是使用可编程门阵列,所有的逻辑包括CPU部分都可以编程实现。许多时髦的FPGA都是为这个目的设计的。 [编辑] 工具同典型的计算机程序员一样,嵌入式系统设计人员也使用编译器、连结器和调试器开发嵌入式系统软件。然而,他们也使用一些大多数程序员不熟悉的工具。 软件工具的来源有如下几种: 嵌入式系统设计人员也使用一些不为普通计算机程序员所熟悉的软件工具:
一些编程语言为嵌入式系统编程提供了一些特殊支持。
[编辑] 调试调试通常使用内部电路仿真器或者其它一些能够在微控制器微码(microcode)内部产生中断的调试器。微码中断让调试器能够在只有CPU工作的硬件中进行操作,基于CPU的调试器能够从CPU的角度来测试和调试计算机的电路。PDP-11开创了这种特性的先河。 开发人员能够仍然使用断点、单步执行以及高级语言进行调试,在许多的调试工具上都有这种能力。另外开发人员在调试实时事件顺序的时候需要记录、使用简单的记录工具。 首先遇到这种问题的个人电脑和大型机程序员经常在设计优先级和可行方法的时候感到困惑。指导、代码审查和非个人风格(egoless)的编程是值得推荐的。 随着嵌入式系统变得越来越复杂,更高层次的工具和操作系统逐渐移植到可行的设备上。例如,蜂窝电话、个人数字助理和其它的消费用计算机需要一些从个人或者这些电子设备制造商之外的公司购买或者提供的一些重要软件。在这些系统中,需要如Linux、OSGi或者Java这样的开放编程环境,这样第三方软件提供上才能够在大规模的市场上销售软件。 大多数这样的开发环境都有一个运行在个人电脑上的参考设计,这种软件的绝大部分都可以在传统的个人电脑上开发。然而,从开放环境移植到专用的电子设备和电子设备的驱动程序开发通常仍然是传统的嵌入式系统软件工程师的工作。在有些情况下, the engineer works for the integrated circuit manufacturer, but there is still such a person somewhere. [编辑] 操作系统
使用Windows XP的因特网收费电话
嵌入式系统经常没有操作系统、专用的嵌入式操作系统(经常是实时操作系统)或者指定程序员移植到这些新系统。 [编辑] 启动嵌入式系统带有启动代码,通常它禁止中断、设置电子设备参数、测试计算机(RAM、CPU和软件),然后开始应用程序运行。许多嵌入式系统从短暂的掉电状态恢复,经常重起而不进行最近的自检。在十分之一秒内重起是常见的现象。 许多设计人员发现LED在指示错误状态上非常有用,它们可以帮助进行故障处理。一个常用的机制是在复位的时候点亮电子设备所有的LED以表明供电和LED正常工作;然后在进行加电自检时由软件改变LED的状态;在此之后,软件用这些LED指示操作过程中的正常或者故障状态。这可以让技术人员、工程师和用户了解系统的状态。一个有趣的例外是电度表(electric power meters)和其它一些大街上的东西,闪烁的指示灯是为了吸引注意力或者表示损坏状态。 [编辑] 内部自检许多嵌入式系统都有一定程度或者一定数量的内部加电自检,自检有几种类型:
[编辑] 可靠性体系根据人们需求的不同可靠性也有不同的定义,有意思的事,可靠性的类型却相对较少,相似可靠性类型的系统使用相似类型的内在检查和恢复方法:
[编辑] 嵌入式软件架构的类型常用的嵌入式软件架构有几种不同的基本类型。 [编辑] 控制迴圈在這種設計中,軟體有一個簡單的循環,這個循環調用各個子程序,每個子程序管理硬體或者軟體的某一部分。中斷通常用來設置標記或者更新軟體其它部分能夠讀取的暫存器。 系統使用簡單的API來完成允許和禁止中斷設置。如果處理得當的話,它能夠在嵌套子程序中處理嵌套調用,在最外面的中斷允許嵌套中恢復前面的中斷狀態。這種方法是實作Exokernel的一個最簡單的方法。 通常在循環中有一些子程序使用周期性的即時中斷控制一組軟體定時器,當一個定時器時間到的時候就會執行相應的子程序或者設置相應的標誌。 任何可能發生的硬體事件都應該有軟體定時器的支持,硬體事件大概每萬億次出現一次錯誤,對於現代的硬體來說大概是一年發生一次,對於以百萬計大規模生產的設備來說,遺漏一個軟體軟體定時器在商業上可能是災難性的。 有時測試軟體運行一組基於軟體的安全定時器,它們周期性地複位硬體中的軟體看門狗。如果軟體錯過一個事件,安全定時器軟體將會捕捉到它。如果安全定時器出錯,看門狗硬體將會複位系統。 可以使用指向每個狀態機函數的指標實作狀態機,函數可以用C++、C或者組合語言等實作。變化的狀態將不同的函數放到指標中,每次循環運行時都會執行函數指標。 許多設計人員建議每個循環讀一次輸入輸出設備、並且保存得到的結果,這樣可以保證邏輯過程的在一致的參數上運行。 許多設計人員喜歡將狀態機設計成每個狀態僅僅檢查一到兩項內容,通常是檢查硬體事件和軟體定時器。 設計人員建議多級狀態機應該讓低層狀態機早於高層狀態機運行,這樣高層就能夠根據正確的信息運行。 如內部燃燒控制這樣的複雜功能通常根據多維表格進行處理,代碼通常進行查表處理而不進行複雜的計算,為了減小表格的大小以及成本軟體可以在條目之間進行差值運算。 在最小的微控制器中,尤其是只有128位元組堆疊的8051中,控制環允許好的連接器使用靜態分配的數據覆蓋本地變數。在這種機制中,離子程序調用樹末端越近的變數得到的記憶體地址越高。當開始一個新的分支的時候,它的變數可以在以前分支遺棄的空間中進行重新分配。 簡單控制迴圈的一個主要缺點是它無法保證響應特定硬體事件的時間。 細心的設計可以很容易地保證中斷不會被長時間禁止,這樣中斷代碼就可以在非常精確的時間運行。 控制環的另外一個主要缺陷是增加新的特性的時候會變得複雜。需要花費很長時間的演算法必須小心地進行分解以使得每次只有一小部分在主循環中運行。 這種系統的優勢是它的簡單性,並且在很小的軟體上,循環執行地很快幾乎沒有人關心它是不可預測的。 它的另外一個優勢是這種系統保證運行軟體的質量,無法將不好的運行結果歸咎為其它的作業系統。 [编辑] 非抢先多任务非抢先多任务系统非常类似于上面的系统,只是这个循环是隐藏在API中的。我们定义一系列的任务,每个任务获得自己的子程序栈;然后,当一个任务空闲的时候,它调用一个空闲子程序(通常调用“暂停”、“等候”、“交出(:en:yield)”等等)。 带有类似属性的架构都带有一个事件队列,有一个循环根据队列列表中的一个域确定删除时间和调用子程序。 这种架构的优点和缺点都非常类似于控制环,只是这种方法添加新的软件更加简单,只需要简单地编写新的任务或者将它添加到队列解释器中。 [编辑] 抢先式定时器使用上面的任何一种系统,但是添加一个按照定时器中断运行子程序的定时器系统,这样就给系统添加了崭新的能力,这样定时器子程序第一次能在一个有保证的时间内运行。 另外,代码第一次能够在非预期的时间访问自己的数据结构。定时器子程序必须要象中断子程序一样进行处理。 [编辑] 抢先式任务使用上面的非抢先式任务系统,从一个抢先式定时器或者其它中断运行。 这样系统就突然变得很不一样了。任何一个任务的代码都有可能损害其它任务的数据 &emdash; 所以它们必须进行切缺的切分。对于共享数据的访问必须使用一些同步策略进行控制,如消息队列、信号灯或者非阻塞同步机制。 经常在这一步开发组织就会购买一套实时操作系统。如果一个组织缺少能够编写操作系统的人才或者操作系统将要在几个产品之上,这可能是一个明智的选择。这通常要将开发计划增加六倒八周,and forever after programmers can blame delays on it. [编辑] 微内核与外内核这种方法试图将系统组织得比大内核更易于配置,而同时提供类似的特点。 微内核是实时操作系统的一个逻辑发展,通常的组织方式是操作系统内核分配内存并且将CPU在不同的线程之间进行切换。用户模式的进程实现如文件系统、用户接口等主要的功能。 微内核在二十世纪五十年代开始首次尝试,但是由于计算机在任务间切换以及在任务间交换数据速度非常缓慢,所以人们放弃了微内核而钟情于MULTICS和UNIX风格的大内核。总体上来说,微内核在任务切换以及任务间通信速度快的时候是比较成功的,在速度慢的时候是失败的。 外内核通过使用普通的子程序调用获得的通信效率很高,硬件以及系统中的软件都是程序员能用也能扩展的。资源内核(可能是库的一部分)分配CPU时间、内存以及其它资源。如多任务、网络以及文件系统这样的大内核特性通过代码库来提供。库可以进行动态的连接、扩展或者共享。不同的应用甚至可以使用的不同的库,但是所有的资源都来自于资源内核。 [编辑] 虚拟机一些航空电子系统使用几个商用计算机。这样更进一步,每个计算机都在模拟它们自身的几个副本,重要的程序同时在几个计算机上运行并且进行投票控制(:en:vote)。 模拟环境的优点就是即使一个计算机出现故障,软件的不同例程能够迁移到正常工作的软件分区,表决的票数并不受影响。 通常虚拟软件运行在计算机的用户模式下,它捕捉、模拟硬件访问和不在用户模式下运行的指令。 [编辑] 检查点计算另外一种常用的机制是两个计算机计算 for a bit,然后将它们的计算结果报到那个点上。如果一个计算机的计算是 nut,它就会被关闭。 [编辑] 办公用(大内核)操作系统这种系统通常在没有系统经费的嵌入式项目中流行,但是从这篇文章的多个作者来看这通常是不正确的,它们的逻辑是:
然而许多工程师并不认同这一点,嵌入式Linux越来越受到人们的欢迎,尤其是在无线路由器和全球定位系统这样的功能强大的嵌入式系统中。其中有下面一些原因:
[编辑] Exotic custom 操作系统一些系统需要安全、及时、可靠或者高效的特性,上面的架构却无法达到,构建这样的系统有一些广为人知的技巧:
这就意味着使用两个优先级和监视器的系统是安全、可靠的,因为它们没有死锁和优先级倒置的问题。如果监视器能够执行到结束,那么就永远不会挂起。如果使用和谐的任务,可能还会相当高效。然而,RMA 无法描述这些系统,优先级最好也不要到处都有,其中包括操作系统和硬件。 [编辑] 外部链接
[编辑] 常见的嵌入式操作系统参见嵌入式操作系统
|


