嵌入式系统传统编程模式
嵌入式系统与通用计算机系统同源,可是因为应用领域和研发人员的不同,嵌入式系统很早就走向相对独立的发展道路,其编程模式与通用计算机系统有较大的区别。一般来说,嵌入式系统传统编程模式有面向寄存器的编程模式、面向API的编程模式、面向端口的编程模式等,其中面向寄存器的编程模式仍然占主导地位。
1.1 面向寄存器的编程模式
嵌入式系统是一个软硬件结合的系统,其中硬件是基础,所有的嵌入式软件都会直接或间接地操作硬件。所谓“面伺寄存器的编程”,就是软件直接操作硬件提供的编程接口来编写嵌入式软件的编程模式。目前,本地硬件提供的编程接口大多数为寄存器,它们通常映射到软件能够直接访问的I/O空间或存储器空间。
面向寄存器的编程模式的基本步骤如图1所示,这是一个蜂鸣器鸣叫的程序。由此可以看出,面向寄存器的编程模式需要对硬件细节非常了解,这是非常繁琐和容易出错的,并且对开发人员的要求较高。
一句话形容:面向寄存器的编程模式就是自己既作将军又作士兵,眉毛胡子一把抓。
1.2 面向API的编程模式
面向寄存器的编程模式非常麻烦,效率低下,不是人人都能胜任的。为了方便嵌入式软件的编写,有些公司编写软件把硬件屏蔽起来形成API,应用软件则通过这些API接口访问硬件。这种通过第三方软件提供的接口来访问硬件的编程模式就是面向API的编程模式。
即使相同的硬件,不同公司提供的API也有很大的出入。有些仅仅提供了一些程序库,对硬件进行简单封装。而有的则提供标准的操作系统接口,如WinCE、嵌入式Linux和VxWorks等。
所有这些API一般是面向本地硬件和部分特定总线(如PCI、USB)的远程硬件的。
面向API编程模式的基本步骤如图2所示。可以看出,面向API的编程模式只需要对硬件细节有大概的了解即可,但需要对API手册进行详细阅读才能开发。不同系统的API可能完全不同,换一种系统,开发人员就需要重新熟悉新的API。另外,不同系统的API功能和性能差异极大,对开发人员的要求也有较大的差别。一句话形容:面向API的编程模式就是手把手教别人干活。
1.3 面向端口的编程
面向端口编程是PLC(可编程逻辑控制器)的编程模式。PLC把所有硬件都虚拟成端口,通过对端口的读写完成对硬件的控制。PLC最初是为了替代继电器编程,对复杂程序的支持比较弱,对远程硬件的支持也比较弱(主要支持PLC厂商自己的配件)。
2 嵌入式系统传统编程方法的困境
2.1 对 比
各种传统的嵌入式系统编程模式有各自特点,如表1所列。
2.2 困 境
最初,嵌入式系统都是独立工作的。传统的编程模式都是面向独立的微控制器(微处理器),操作的硬件都是本地硬件。
随着时间的推移,嵌入式系统由独立工作走向了网络控制(典型的系统就是集散控制系统),此时嵌入式系统的编程模式依然是面向独立的微控制器(微处理器)。要把这些嵌入式系统组成网络,需要为所有控制器增加兼容的通信接口硬件,并设计兼容的通信协议。而且,每个系统需要对硬件通信接口编程及对通信协议编程后才可能组成网络。这个设计无疑是复杂的。
用面向寄存器的编程模式编写联网控制系统的步骤如图3所示,面向API的编程模式的步骤如图4所示。图3、图4的右边是编写控制远程蜂鸣器鸣叫程序的步骤。至于面向端口的编程模式,目前主要是PLC,它的开发步骤比较简单,读者可以参考PLC的开发手册。不过,PLC一般支持有限的远程设备,并且成本高昂,很多时候并不适用。通过图3和图4可以看出,对于联网的控制系统,这两种编程模式的步骤基本相同。面向寄存器的编程模式开发难度很大,而面向API的编程模式相对小一些,不过任务依然艰巨。
各种编程模式的对比如表2所列。
现在,组网的范围更加广泛:不但需要本地组网,还需要远程组网;不但控制设备之间需要互连,控制设备与普通计算机之间还需要互连,以及不同厂商的设备之间也要互连。这些要求无疑加剧了系统编程的复杂性。
3 面向设备的编程模式
3.1 范 例
面向设备的编程模式是由面向API的编程模式和面向端口的编程模式继承发展而来的,具有两者的优点,避免了各自的缺点,同时极大地增强了组网能力。
这里依然以开发控制远程蜂鸣器的嵌入式系统为例,其开发流程如图5所示。图5的左边是面向设备的编程模式,右边是开发步骤。
通过查看远程设备图,得知蜂鸣器的端口地址为0x1111,写1为鸣叫,写0为停止鸣叫。
这种编程模式非常简单。事实上延时功能已经定义成本地端口,真实的程序将更简单。面向设备编程模式与传统编程模式的对比如表3所列。
3.2 设计目标
针对目前嵌入式系统设计的困境,本文提出“面向设备的编程”这一概念。研发人员不需要考虑硬件细节和网络细节,使用同一种方式操作本地硬件和远程硬件。
与传统编程模式不同,面向设备的编程模式把所有通过网络连接的嵌入式系统和计算机作为一个整体来考虑。研发人员只需要知道设备地址和设备内端口地址的分配即可,不需要知道设备如何连接到系统,可以通过有限的几个函数操作设备。
3.3 特 点
AnyWhere最大的特点是着眼于系统,是系统级解决方案。一个系统中的所有嵌入式设备都使用AnyWhere兼容设备,整体效果最佳。除了这个特点外,AnyWhere还有以下特点:
①使用ANSI C编程。将来可能增加编程语言支持。
②编程接口统一。无论操作设备的什么功能,都使用有限的几个函数操作。
③编程不区分远程设备和本地硬件。系统保留1个系统地址(符号为AW_LOCAL_ADDR,值为0x00000000)用于识别本地设备,用这个地址操作的就是本地设备。大多数情况下,设备也可以使用设备的真实地址来访问本地硬件。这样,设备可以使用同样的接口访问本地硬件和远程设备。
④多协议多网络支持。AnyWhere默认协议计划支持RS232、RS485、RS422、以太网、CAN、USB等网络。AnyWhere还计划支持ModeBus、iCAN、CANOpen、DeviceNet、J1939、DMX512、MVB等协议。用户还可以通过多协议接口增加特定的协议。
⑤协议及链路自动动态匹配。研发人员只需要知道设备的地址就可以编程,而不需关心主控设备与被控设备之间的网络与协议匹配问题。系统会自动选择两者均支持(并且当前网络结构支持)的协议。如果网络结构发生变化,系统会再次主动选择协议。这些过程都是透明的,研发人员无需关心。
⑥提供被控设备编程接口。用户可以通过这个接口设计特殊的被控设备。
4 基本设计思想
(1)总体设计思想
AnyWhere把所有用网络连接起来的嵌入式系统作为一个整体来考虑。依据其在系统中的作用,把嵌入式系统分为主控设备和被控设备两类。
主控设备通过远程调用来控制被控设备。每当主控设备调用AnyWhere的主机接口核心函数时,对应的被控设备执行相应的函数。被控设备的函数执行完毕后,把返回值和执行结果反馈给主控设备,主控设备获得执行结果,函数返回。
(2)基本框图
AnyWhere的基本框图如图6所示。
(3)一般处理流程
为主控设备访问远程设备中awRead()函数的一般处理流程是:主控设备首先查找ARP表,如果ARP表中存有被控设备信息,调用被控设备函数开始执行;如果ARP表中不存在此远程设备的情况,则需要请求添加此设备;在远程设备添加成功后,调用被控设备函数开始执行;程序处理完成后应答返回。
5 主要的用户编程接口
5. 1 主控设备编程接口(核心编程接口)
这是一般用户使用的接口,也是最常用的API。这部分有4个函数,分别是awRead()、awWrite()、awReadEx()和awWriteEx()。其中函数awRead()和awWrite()是对指定设备的指定端口用默认的模式读写,读写的数据都会转化为32位无符号数。而awReadEx()和awWriteEx()用于对端口一次读写多个数据,需要指定读写模式,这个模式还必须与端口的模式一致。
5.2 被控设备编程接口
在设计一个控制系统时,被控设备一般会选择标准设备,不需要用户编程。如果使用非标准的被控设备,就需要进行产品研发。从图6可以看出,被控设备的应用程序仅仅是初始化而已。如果用户选择广州致远电子有限公司的半成品模块,大多数情况下也无需开发,只需通过向导(PC机程序)配置需要的功能就可以生成需要的代码。如果这些半成品模块不能完全满足系统需求,就要进行研发。