1 .概述
PC的软件开发过程包括程序编辑、编译、链接、调试,最后到程序运行,其整个过程都在同一个PC平台上完成。而嵌入式系统由于资源有限,系统本身不具备自主开发能力。即使设计完成后,用户也不能在本系统上对其中的软件进行修改和调试。嵌入式系统的开发必须借助于在宿主机(如PC)上的一套专用的开发环境,包括设计、编译、调试及下载等工具,采用交叉开发的方式来进行完成。嵌入式系统采用这种交叉开发、交叉编译的开发模式,主要因为它是一种专用的计算机系统,是在有限的资源下,采用量体裁衣、量身定制的方法构造的。
一个嵌入式系统的开发环境一般包括开发用的宿主机、嵌入式目标机、调试器和软件开发工具,它们之间通过串口、JTAG(并口)和网络接口等进行通信。通常在宿主机上完成程序编写和编译,将高级语言程序编译成可以运行在目标机(如嵌入式产品)上的二进制程序,然后利用宿主机上丰富的资源和良好的开发环境开发、仿真调试目标机上的软件,通过物理连接,将交叉编译生成目标代码传输并装载到目标机上,使用交叉调试器在监控程序或实时内核/操作系统的支持下进行实时分析和调度,最后在目标机特定的环境下运行。
2 .开发流程
用户把嵌入式软件的源代码表述为可执行的二进制映像的过程包括下面三部分内容:首先,每一个源文件都必须编译到一个目标文件(Object File)上;其次,将产生的所有目标文件链接成一个目标文件,称之为可重定位程序(Relocatable Program);最后,在一个称为重定址(Relocation)的过程中,要把物理存储器地址指定给可重定位程序里的每一个相对偏移处,这一步的结果就是一个可以运行在嵌入式系统上的包含可执行二进制映像的文件。图1-13给出了嵌入式软件的开发流程。
图1-13 软件开发流程
综上所述,嵌入式软件的开发可主要分为目标文件的生成、调试和固化运行三个步骤。嵌入式软件系统的生成是在宿主机上进行的,利用软、硬件各种工具完成对应用程序的编辑、交叉编译和交叉链接工作,生成可供调试或固化的目标程序。其中通过交叉编译器和交叉链接器可以在宿主机上生成能在目标机上运行的代码,而交叉调试器和硬件仿真器等则用于完成在宿主机与目标机间的嵌入式软件的调试。调试成功后还要使用一定的工具将程序固化到目标机上,然后脱离与宿主机的连接,启动目标机。这样目标机就可以在没有任何干预的情况下,程序能自动地启动运行。
建立交叉开发环境是进行嵌入式软件开发的第一步,目前常用的交叉环境主要有开源和商业两种类型:开源的交叉环境的典型代表是GUN工具链,可以支持ARM、x86、MIPS、PowerPC等多种处理器;商业的主要有ARM Software Development Toolkit、Microsoft Embedded Visual C++等。
经过开发及调试后会生成嵌入式映像文件,该文件是嵌入式计算机上的一个可执行文件。在执行之前要将其下载到目标机的存储器中,才能启动执行。以ARM软件开发为例,ARM集成开发环境中的各种源文件(汇编、C以及C++程序)经过ARM编译器编译之后,生成ELF格式的目标文件。这些目标文件和相应的C/C++运行库经过ARM链接器链接后,生成.axf映像文件,然后下载到开发板上调试运行,最后使用fromelf工具将映像文件中的调试信息和注释过滤掉生成二进制的可加载文件(扩展名为.bin),将其文件固化写入嵌入式设备的ROM中。这样目标机加电后就可以开始自启动,执行程序进行工作了。
在嵌入式软件开发过程中,目标机上嵌入式软件的运行方式有程序调试下载启动方式和程序固化自启动方式两种。在不同的方式下,程序代码或数据在目标机内存中的定位也有所不同。宿主机上提供一定的工具或者手段对目标程序的运行方式和内存定位进行选择和配置,链接器再根据这些配置信息将目标模块和库文件中的模块链接成目标程序。
3 .开发工具
“工欲善其事,必先利其器”,嵌入式软件开发工具的集成度和可用性将直接关系到嵌入式系统的开发效率。ARM的开发工具包括有编译器、汇编器、链接器、调试器、操作系统、函数库、评估板、JTAG调试器、在线仿真器等。目前世界上约有几十家公司提供不同类型的产品。用户在开发嵌入式系统时,针对不同的开发阶段以及开发需求,需要选择不同的开发环境以及工具,合理使用嵌入式开发工具可以加快开发进度,节省开发成本。因此,正确建立交叉开发环境是进行嵌入式软件开发的第一步,针对选择的嵌入式系统的不同,相应开发环境也是有所区别的。
嵌入式系统在开发过程中,主体上可分为嵌入式系统的裸机开发阶段和基于操作系统及应用程序开发二个阶段。其中,嵌入式系统裸机开发阶段主要是指针对开发Bootloader或者接口调试等系统底层开发阶段。而基于操作系统及应用程序开发阶段主要是指在开发嵌入式操作系统(包括移植和裁剪等工作)以及相关应用程序编写的阶段。
在嵌入式软件开发过程中,进行程序调试时采用在宿主机和目标机之间进行的远程调试方式,调试器运行在宿主机的通用操作系统之上,但被调试的进程却是运行在基于特定硬件平台的嵌入式操作系统中,调试器和被调试进程通过串口或者网络进行通信。调试器可以控制、访问被调试的进程,读取被调试进程的当前状态,并能够改变被调试进程的运行状态。
远程调试允许调试器以串口、并口、网络、JTAG或者专用的通信方式控制目标机上被调试进程的运行方式,并具有查看和修改目标机上内存单元、寄存器以及被调试进程中的变量值等各种调试功能。
嵌入式电路系统设计主要适用于电子玩具、工业控制、民用电器、机电一体化产品、航天航海等众多领域。它们的应用开发不单只是软件的开发,其开发语言也与硬件密切相关。所以只有开发者对嵌入式系统的内部结构非常了解,才能编好软件。而嵌入式系统的开发应用还涉及硬件扩展接口和各类传感器,更重要的是必须尽可能地了解各学科中适应嵌入式系统完成的控制项目以及控制过程。
掌握嵌入式电路系统的应用开发需要一个过程。首先必须掌握数字电路和模拟电路方面的知识,此外还必须学习嵌入式处理器的硬件结构、扩展接口和编程语言方面的内容。初次开发时由于没经验,可能要经过多次反复才能完成项目。开发人员需要具有硬件设计方面知识的积累、软件程序设计和设计经验方面的积累。
过去擅长于软件设计的编程人员一般对硬件电路设计敬而远之,硬件设计和软件设计被认为是性质完全不同的技术。一个软件设计工程师一直编写程序,却对硬件知识了解甚少。而一个嵌入式系统设计师不仅要与硬件打交道(如进行系统硬件设计),结合硬件编写正确的嵌入式软件程序。另外还要能够区分某一个问题是由软件还是硬件错误引起的,必须能够阅读硬件原理图,并有能力进行更正电路中的错误。
随着电子信息技术和计算机技术的飞速发展,特别是硬件描述语言HDL的发明,硬件设计方法发生了变化,数字系统的硬件组成及其行为完全可以用HDL来描述和仿真。在这种情况下,要求设计人员都要借助HDL工具来描述硬件电路的行为、功能、结构、数据流、信号连接关系和时序关系,设计出满足各种功能要求的硬件系统。
电子设计辅助工具EDA一般允许有两种设计输入工具,分别适应硬件电路设计人员和软件设计人员的两种不同背景的需要,让具有硬件背景的设计人员使用已习惯的原理图输入方式,而让具有软件背景的设计人员使用硬件描述语言HDL输入方式。由于采用HDL描述输入,因而与系统行为描述更接近,且更便于综合、传递和修改,还能建立独立于工艺的设计文件。所以,擅长软件编程的人一旦掌握了HDL和一些必要的硬件知识,往往可以比习惯于传统设计的工程师设计出更好的硬件电路和系统。正因为如此,习惯于传统设计的工程师应该学会用HDL来描述和编程。
由于嵌入式系统是软/硬件紧密结合的系统,因此嵌入式电路系统的开发通常是软、硬件并行设计、开发的过程。硬件开发是嵌入式系统开发的基础,软件的开发是建立在硬件之上,软、硬件设计的巧妙结合是项目开发质量保证的关键。在硬件开发设计中开发者首先应学习应用最新嵌入式微处理器相关功能,还有外部扩展功能的增强等。其次,在扩展接口的开发尽可能采用FPGA或CPLD等器件开发。这类器件都有开发平台的支持,开发难度较小,开发出的硬件性能可靠、结构紧凑、利于修改、保密性好。这种方法也是硬件接口开发的趋势。
4 .可靠性设计
有时开发一个嵌入式系统应用项目,在仿真调试完成后系统运行正常,当进入现场后就出现了不能正常运行或运行时好时坏的现象,而脱离现场后一切又都正常,这种现象就涉及到可靠性问题。解决这种问题可以从以下几个方面考虑:
● 选择性能好、抗干扰能力强的供电系统,尽量减少从电源引入的干扰;
● 设计电路板时排除可能引起干扰的因素,合理布线可避免高频信号的干扰;
● 选择较好的接地方式,如模拟地和数字地采用一点接地方式,驱动大电流信号时采用光电隔离;
● 数据采集时进行数字滤波处理,常用的数字滤波方式有程序判断滤波、中位值滤波、算术平均滤波、递推平均滤波法、防脉冲干扰平均值滤波、一阶滞后滤波等方式。
由于干扰问题可能是由于不同的原因所引起的,所以在进行设计时要根据项目应用场所分析可能出现的干扰,有目的地在硬件系统中加入抗干扰电路,在软件设计中加入抗干扰算法。嵌入式系统出现故障的特性像一个浴缸曲线,在系统建立的生命初期,故障率是很高的;在产品的有效生命期,故障率比较低;一旦达到生命末期,硬件模块的故障率又提高了。