嵌入式程序是运行于嵌入式设备中的程序系统。嵌入式设备一般为由单片机等专用MCU和简单外设构成的专用计算机系统,广泛存在于各类工业以及民用设备中,包括各种家电、汽车、仪器仪表、各种智能设备、数控机床等。
嵌入式系统一般都有具体的预先规划的功能要求,而且比较固定、不随时间变化(也有可以更新程序的设备,但更新频率也很低)。因此软硬件都为其功能优化。嵌入式系统往往生产数量巨大,其对成本一般比较敏感,因此配备的资源,包括计算能力、存储、内存、外部接口等都比较有限。
嵌入式系统运行于片上系统(SoC)。基本由MCU、Flash/ROM、SRAM、外部接口(UART、USB等)构成,一般不配备硬盘等外部设备,程序放在Flash/ROM中,在其中直接运行、或复制到内存中运行。由于资源受限,因此要求程序短小精悍。
1. 嵌入式程序任务的基本结构
嵌入式程序一般设计为连续运行,即除了硬件的原因(维修、更换)以外,系统不停机持续运行。因此,嵌入式程序的基本结构为事件驱动—事件处理模式,如图 1所示。
图 1 嵌入式程序基本结构
程序总是处于待机状态,等待外部事件输入。此处所说的事件是一个广义的概念,指来自外部的所有触发,包括传感器采集的信息、执行器的执行结果反馈、来自外部接口或软件内部的通信数据(包括来自外部的控制命令)、定时器的超时等等。而且外部事件是对处理程序而言的。在一个多任务(此处的任务相当于Linux中的线程)系统中,处理程序就是一个任务,因此来自其他任务的输入也被当作外部事件。
收到外部事件以后,程序开始对事件进行处理,并将处理结果反馈给外部,反馈结果包括对外的数据传输(包括给其他任务的)、控制外部设备进行指定的操作等。同时,程序回到待机状态,等待下一次外部事件的输入。下图是一个多任务的事件处理模型。
图 2 多任务事件处理模型
在这样一个多任务模型中,任务之间除了内部事件的通信、没有任何其他的交互方式。而各个任务的基本结构都是相同的。这样将内部事件与外部事件统一成一样的形式,一方面简化了任务的结构,可以将内部事件与外部事件统一处理;另一方面,如果随着系统的发展,需要将某个或者几个任务移动到别的MCU上时,任务本身毋需修改,使移植工作简单易行。
2. 嵌入式程序的实现
在单任务系统中,这个结构实际上构成了整个应用程序的框架;而在多任务系统中,这则是每个任务的基本框架。转换成伪代码,如下所示。
while(1) {
if(receiveEvent()) { handleEvent(); } } |