的一个最简单的方法。
通常在循环中有一些子程序使用周期性的实时中断控制一组
软件定时器,当一个定时器时间到的时候就会运行相应的子程序或者设置相应的标志。
任何可能发生的硬件事件都应该有软件定时器的支持,硬件事件大概每万亿次出现一次错误,对于现代的硬件来说大概是一年发生一次,对于以百万计大规模生产的设备来说,遗漏一个软件软件定时器在商业上可能是灾难性的。
有时测试软件运行一组基于软件的安全定时器,它们周期性地复位硬件中的
软件看门狗。如果软件错过一个事件,安全定时器软件将会捕捉到它。如果安全定时器出错,看门狗硬件将会复位系统。
可以使用指向每个
状态机函数的
指针实现状态机,函数可以用
C++、
C或者
汇编语言等实现。变化的状态将不同的函数放到指针中,每次循环运行时都会运行
函数指针。
许多设计人员建议每个循环读一次输入输出设备、并且保存得到的结果,这样可以保证逻辑过程的在一致的参数上运行。
许多设计人员喜欢将状态机设计成每个状态仅仅检查一到两项内容,通常是检查硬件事件和软件定时器。
设计人员建议多级状态机应该让低层状态机早于高层状态机运行,这样高层就能够根据正确的信息运行。
如内部燃烧控制这样的复杂功能通常根据多维表格进行处理,代码通常进行查表处理而不进行复杂的计算,为了减小表格的大小以及成本软件可以在条目之间进行差值运算。
在最小的微控制器中,尤其是只有128位组
堆栈的
8051中,控制环允许好的
连接器使用静态分配的数据覆盖本地
变量。在这种机制中,离子程序调用树末端越近的变量得到的存储器地址越高。当开始一个新的分支的时候,它的变量可以在以前分支遗弃的空间中进行重新分配。
简单控制循环的一个主要缺点是它无法保证响应特定硬件事件的时间。
细心的设计可以很容易地保证中断不会被长时间禁止,这样中断代码就可以在非常精确的时间运行。
控制环的另外一个主要缺陷是增加新的特性的时候会变得复杂。需要花费很长时间的
算法必须小心地进行分解以使得每次只有一小部分在主循环中运行。
这种系统的优势是它的简单性,并且在很小的软件上,循环运行地很快几乎没有人关心它是不可预测的。
它的另外一个优势是这种系统保证运行软件的质量,无法将不好的运行结果归咎为其他的操作系统。
非抢先多任务
非抢先多任务系统非常类似于上面的系统,只是这个循环是隐藏在
API中的。我们定义一系列的任务,每个任务获得自己的子程序栈;然后,当一个任务空闲的时候,它调用一个空闲子程序(通常调用“暂停”、“等候”、“交出(
yield)”等等)。
带有类似属性的架构都带有一个事件队列,有一个循环根据队列列表中的一个域确定删除时间和调用子程序。
这种架构的优点和缺点都非常类似于控制环,只是这种方法添加新的软件更加简单,只需要简单地编写新的任务或者将它添加到队列解释器中。
抢先式定时器
使用上面的任何一种系统,但是添加一个按照
定时器中断运行子程序的定时器系统,这样就给系统添加了崭新的能力,这样定时器子程序第一次能在一个有保证的时间内运行。
另外,代码第一次能够在非预期的时间访问自己的数据结构。定时器子程序必须要象中断子程序一样进行处理。
抢先式任务
使用上面的非抢先式任务系统,从一个抢先式定时器或者其他中断运行。
这样系统就突然变得很不一样了。任何一个任务的代码都有可能损害其他任务的数据 &emdash;
所以它们必须进行切缺的切分。对于共享数据的访问必须使用一些同步策略进行控制,如消息队列、信号灯或者
非阻塞同步机制。
经常在这一步开发组织就会购买一套
实时操作系统。如果一个组织缺少能够编写操作系统的人才或者操作系统将要在几个产品之上,这可能是一个明智的选择。这通常要将开发计划增加六倒八周,and
forever after programmers can blame delays on it.
微内核与外内核
这种方法试图将系统组织得比大内核更易于配置,而同时提供类似的特点。
微内核是实时操作系统的一个逻辑发展,通常的组织方式是操作系统内核分配内存并且将CPU在不同的线程之间进行切换。用户模式的进程实现如文件系统、用户接口等主要的功能。
微内核在二十世纪五十年代开始首次尝试,但是由于计算机在任务间切换以及在任务间交换数据速度非常缓慢,所以人们放弃了微内核而钟情于
MULTICS和
UNIX风格的大内核。总体上来说,微内核在任务切换以及任务间通信速度快的时候是比较成功的,在速度慢的时候是失败的。
外内核通过使用普通的子程序调用获得的通信效率很高,硬件以及系统中的软件都是程序员能用也能扩展的。资源内核(可能是库的一部分)分配CPU时间、内存以及其他资源。如多任务、网络以及文件系统这样的大内核特性通过代码库来提供。库可以进行动态的连接、扩展或者共享。不同的应用甚至可以使用的不同的库,但是所有的资源都来自于资源内核。
虚拟机
一些航空电子系统使用几个商用计算机。这样更进一步,每个计算机都在模拟它们自身的几个副本,重要的程序同时在几个计算机上运行并且进行投票控制(:en:vote)。
模拟环境的优点就是即使一个计算机出现故障,软件的不同例程能够迁移到正常工作的软件分区,表决的票数并不受影响。
通常虚拟软件运行在计算机的用户模式下,它捕捉、模拟硬件访问和不在用户模式下运行的指令。
检查点计算
另外一种常用的机制是两个计算机计算 for a bit,然后将它们的计算结果报到那个点上。如果一个计算机的计算是
nut,它就会被关闭。
办公用(大内核)操作系统
这种系统通常在没有系统经费的嵌入式项目中流行,但是从这篇文章的多个作者来看,这通常是不正确的,它们的逻辑是:
·
操作系统是经过特殊封装的重用代码库。如果这些代码有用,设计人员就会节省时间和金钱,否则它们就是无用的。
·
商务系统的操作系统没有嵌入式硬件的接口。例如,如果要用Linux写一个马达控制器或者电话交换机,绝大部分的实际控制操作都是
IOCTL调用,同时,正常的读、写和查询界面都是无用的。所以操作系统对于实际的开发妨碍很大。
·
大多数的嵌入式系统不处理办公事务,所以办公操作系统的大部分代码都被浪费了。例如,绝大多数的嵌入式系统从来都不使用文件系统或者屏幕,所以文件系统和图形用户界面部分就是浪费的,这些不用的代码只会影响系统的可靠性。
·
办公用操作系统保护硬件不让用户程序操作,这就严重地妨碍了嵌入式开发工作。
·
操作系统必须移植到嵌入式系统上,也就是说,硬件驱动程序无论如何都必须重写,这也是操作系统最难的部分,所以使用这样的操作系统几乎没有功效。
·
操作系统真正有用、可移植的特性是小段代码。例如,一个基本的
TCP/IP接口大约有3000行代码,另外的一个例子是大约同样大小的简单文件系统。如果设计需要这些代码,能够使用少于嵌入式系统开发10%的经费就能完成,不需要支付版权费用,只需要简单地重写就可以了。如果系统这些代码有足够的通用性,嵌入式系统杂志封面的后面通常有公司销售没有版权费的C语言实现代码。
然而许多任务程师并不认同这一点,
嵌入式Linux越来越受到人们的欢迎,尤其是在无线
路由器和
全球定位系统这样的功能强大的嵌入式系统中。其中有下面一些原因:
·
有现成的移植到普通嵌入式芯片的实现代码。
·
它们允许重用公开获得的
设备驱动程序、
网页服务器、
防火墙或者其他代码。
·
开发系统能够从许多特性组合开始,在发布的时候可以剔除不需要的功能,从而节约所消耗的内存。
·
许多任务程师认为在用户模式运行应用程序更为可靠、更容易调试,所以开发过程更容易、代码更易于移植。
·
许多嵌入式系统没有控制系统那样对于实时性的严格要求,对于许多应用来说如嵌入式Linux这样的系统的响应速度就已经足够了。
·
要求更快的响应速度,而不是可靠性的特性,通常放到了
硬件上。
·
许多实时操作系统都针对每件产品收取费用,当产品是消费品时,这项费用是巨大的。
Exotic
custom 操作系统
一些系统需要安全、及时、可靠或者高效的特性,上面的架构却无法达到,构建这样的系统有一些广为人知的技巧:
·
雇佣一个真正的
系统程序员。他们的花费很小,但是能够节约数年的调试以及相关的收入损失。
·
RMA (
rate
monotonic
analysis),可以用来评估一组任务能否在特定的硬件系统下运行,在最简单的形式下,设计人员保证最快完成的任务有最高的优先级,平均来说
CPU 至少有 30% 的空闲时间。
·