1 概 述
嵌入式系统具有专用性强、外围设备多样的特性,这决定了其应用的硬件环境差异性较大。系统软件模块与硬件之间的接口是嵌入式实时系统的主要特征,是系统设计过程中的必需环节,也是影响嵌入式系统应用前景的关键问题之一。硬件抽象层(Hardware AbSTractiON Layer,HAL)的引入可有效解决这一问题。HAL是将硬件平台与应用软件隔离开来的软件层次,通过硬件抽象技术实现硬件相关和硬件无关两部分程序代码的隔离,为应用软件提供一个没有硬件特性的接口。硬件抽象层的引入不仅是系统体系结构设计方法的改进,更直接关系到整个系统的开发模式以及嵌入式操作系统的可移植性。硬件抽象层的引入大大推动了嵌入式系统开发的规范化进程。
EMC是一个开放源代码的用于机床或机器人等运动控制系统的计算机控制软件。它能同时驱动9轴电机。其运动控制特包括:刀具半径和长度补偿、轴同步运动、自适应进给速度、恒速度控制等。EMC2在原有EMC软件的基础上加入了许多新的特性和功能,其中包括了HAL和软件PLC模块ClassicLadder。ClassicLadder是一个基于LGPL协议的梯形图解释器。它随着EMC2一起发布,可以与EMC2的HAL一起工作。本文中的控制系统利用EMC2的HAL为软PLC中的应用程序提供底层硬件操作支持,提高了应用程序的平台无关性与可移植性。
2 硬件架构
控制器是锂电池卷绕恒张力控制器,采用符合PC/104总线规范的单板计算机(以下简称PC104)与基于FPGA的专用主机板相结合的方法构建系统硬件。PC104中运行实时Linux,ClassicLadder及HAL作为实时模块加载到Linux系统中。
系统硬件框图如图1所示。其中ADS8361为12位模/数转换器,用于采集张力值等模拟量;AD5624为数/模转换器,用于控制直流电机转速及气压阀压力值;FPGA控制所有外围芯片,并产生电机脉冲方向信号,同时对电机编码器信号进行计数;CPLD控制I/O输入/输出点,并与FPGA交换信息。利用EMC2中HAL的实现原理,可编写组件将硬件系统所有设备抽象成引脚和函数的形式,供软PLC在需要时加载。
3 EMC2中HAL的基本概念
HAL,Hardware Abstraction Layer,硬件抽象层 Windows NT的一个目标是使操作系统可跨平台移植。理想情况下,当一种新机器问世时,他应该可以仅仅使用新机器的编译器来重新编译这个操作系统,就让他首次运行。但是,现实中并不能这样做。虽然上层的操作系统能够完全移植(因为它们的处理大多是内部数据结构),但底层处理的是设备寄存器、中断、DMA和其他的硬件特性,这些都是因机器而不同的。即使大部分底层代码是用C语言编写的,它也不能仅仅从X86上拿出来放到Alpha上,然后重新编译、重新启动,因为X86和ALPHA之间存在许多小的硬件差别,它们和不同的指令集相关并且不能被编译器隐藏。
4 HAL架构
系统软件架构如图2所示。用HAL将各I/O通道、ADC通道、DAC通道、脉冲通道、编码器通道抽象成Pin,将对硬件各模块的操作抽象成各个Function,将Pin和Function封装在命名为hal_CNC的Component中。
硬件在Component中被映射为如下数据结构:
由上述结构可以看出,每个Pin对应一个相应类型的指针,该指针指向的内存区便存放该引脚的值。
5 基于HAL的驱动程序编写
考虑内存映射I/O和I/O端口的对比。一些机器具有前者,一些机器具有后者。驱动程序该怎样编写?是否使用内存映射呢?强制选择会使驱动程序无法移植到另一种实现方式的机器上,为此,硬件抽象层专为驱动程序的编写者提供了三个读设备寄存器的函数和另外三个写寄存器的函数:uc=READ_port_UCHAR(port); WRIte_PORT_UCHAR(port, uc) us=READ_PORT_USHORT(port); WRITE_PORT_USHORT(port, us),ul=READ_PORT_ULONG(port); WRITE_PORT_LONG(port, ul) 这些函数分别读写无符号8位、16位、32位的证书到特定的端口。由HAL决定是否需要内存映射I/O,这样,一个驱动程序可以不被修改而在具有不同设备寄存器实现的机器间移植。驱动程序常由于各种原因而访问特定的I/O设备。在这个硬件层上,一个设备的某个总线上会有一个或多个地址。由于现代计算机常有多种总线(PCI、PCI-E、SCSI、USB等),很可能两个或更多设备具有相同的总线地址,因此需要通过某种方式来区分它们。HAL提供了一个服务,该服务通过将总线相连的设备地址映射到系统范围内的逻辑地址来识别设备。这样,驱动程序就不需要知道哪条总线上有哪个设备了。这些逻辑地址与操作系统为用户程序提供的指向文件和其他系统资源的句柄是类似的。这种机制也使总线结构的属性和寻址方式对于高层不可见。
6 HAL的使用
以DAC为例,在Linux下的命令行输入“halrun”进入EMC2的HAL运行界面,输入:
loadrt threads namel=thread periodl=1000000
创建名为“thread”的线程,该线程执行周期为1 ms。
执行:
loadrt hal_CNC
将所编写的硬件系统组件调入,执行:
addf CNC.DAC.write thread
将DAC的写函数加入到前面创建的线程thread,使之以与thread相同的执行周期被调用。然后使可通过控制DAC的引脚来输出相应的电压。如:
setp CNC.DAC.0.value 1
该语句将使电路板上的DAC输出端子输出1 V的电压。
用类似的方法将其他软件模块通过与HAL的引脚连接,便实现了其他软件对HAL的调用。
7 HAL在ClassicLadder中的调用
以从DAC输出5 V为例,将classicladder的一个名为“classicladder.0.s320ut-00”的有符号32位整型Pin赋值为5。该值经过HAL中的一个类型转换Component“s32tofloat”变为浮点数,再连接到hal_CNC中的DAC单元的引脚“CNC.DAC.0.value”,便在实际硬件电路板的DAC输出端输出5 V的电压。引脚连接如表1所列。
其中“→”和“←”表示引脚之间的连接,用HAL中的Sig-nal实现。
在软PLC中设置变量W10的值为5,则在DA输出端子引脚上用万用表测到5 V的电压。软PLC中的操作输出如图3所示。
其中4个窗口表示DAC的4个通道,分别令DAC输出5 V、2 V、3 V、4 V的电压。
8 结 论
实践证明,HAL的引入可极大提高嵌入式软件实现的硬件无关性。从软件的角度来看,其面向的硬件具有同质的接口,对硬件的操作具有相似的方法与架构,极大地简化了软件对硬件的控制,方便了同类软件在不同硬件平台间的移植。这就为软硬件同步设计、分工协作奠定了良好的基础。该架构已成功应用在文中所述的锂电池卷绕恒张力控制器中,取得了良好效果。