林海,赵昶宇
嵌入式系统软件调试和固化方法研究
林海1,赵昶宇2
(1.海军装备部驻天津地区第二军事代表室,天津 300308;2.天津津航计算技术研究所,天津 300308)
嵌入式软件调试和固化已经成为软件开发过程中不可或缺的一部分,嵌入式软件调试环境为嵌入式软件的调试和固化提供了广阔便利的发展空间。阐述了嵌入式软件的常用调试工具、调试方法和固化方法,并给出了嵌入式软件调试和固化的经验,对嵌入式软件的开发调试具有指导意义。
嵌入式系统;软件调试;调试工具;软件固化
嵌入式软件的调试和固化是嵌入式软件开发过程中非常重要的组成部分,软件开发人员在源代码设计完成后,需要在指定的硬件平台上进行调试、验证,最终形成目标码后对软件产品进行固化,软件设计人员对软件调试、固化过程和经验技巧进行充分了解,可以在很大程度上提高工作效率,避免出现低层次质量错误。
由于目前嵌入式软件调试平台种类很多,按照开发调试环境可划分为具有集成开发调试环境的仿真器调试平台、简易的监控调试平台、黑盒调试平台以及集成交叉开发环境四大类。
软件设计人员可以在集成仿真环境下进行源代码的编译、链接、生成目标文件,与目标机建立联系后,可动态加载目标文件执行,灵活设置断点、观测变量、访问内存、寄存器、跟踪打印调试信息。近年来发布的主流处理器都支持仿真器调试,如TI的C3X系列、C5X系列、C6X系列,AD公司的TS201、0MAP、ARM系列等处理器都有完善的集成仿真调试环境。
对于386EX芯片,利用系统提供的编译程序进行编译连接生成目标文件,在386EX提供了监控调试环境下,主机和目标板通过RS-232串口建立通讯关系,软件开发人员可以进行目标文件的在线加载,在源程序中插桩加入断点的方式进行调试,可以在进入断点后,观测寄存器和程序执行状态。
对于早期开发的8051、80196系列的芯片,部分产品只能在黑盒环境下进行软件调试,软件设计人员可以在源程序中进行插桩,加入相关的调试信息,通过监测口进行调试。
对于X86、PPC、ARM、MIPS系列的处理器芯片,软件开发人员可以在Tornado/WorkBench集成开发环境下进行软件调试。一般在宿主机上进行程序的编制和编译,调试、测试和执行则需要将编译好的目标文件下载和链接到运行着嵌入式实时操作系统的目标机上,宿主机和目标机之间通过串口或者以太网接口进行通信。软件开发人员可以借助Tornado/WorkBench自带的调试器配合目标机共同完成对被调试程序执行状态的实时跟踪,从而快速有效地对程序错误进行定位、纠正,提高调试效率。
在Tornado/WorkBench集成开发环境下,常用的调试和测试工具有:①内存分析工具。用于处理动态内存分配中存在的缺陷。当动态内存被错误分配后,通常难以再现,可能导致失效难以跟踪,使用内存分析工具可以避免这类缺陷进入功能测试阶段。但该工具可能会对代码的性能造成很大影响,从而严重影响实时操作。②性能分析工具。该工具会提供有关的数据,说明执行时间是如何消耗的,是何时消耗的,以及每个例程所用的时间。性能分析工具不仅能指出哪些例程花费时间,而且与调试工具联合使用可以引导开发人员查看需要优化的特定函数,性能分析工具还可以引导开发人员发现在系统调用中存在的错误以及程序结构上的缺陷。③GUI测试工具。GUI测试工具可以作为脚本工具在开发环境中运行测试用例,其功能包括回放操作记录、抓取屏幕显示供以后分析和比较、设置和管理测试程序。很多嵌入式设备没有GUI,但常常可以对嵌入式设备进行插桩来运行GUI测试脚本。该工具可以节省功能测试和回归测试的时间。 ④覆盖分析工具。一般在代码的调试和测试时可以使用代码覆盖工具跟踪哪些代码被执行过,分析过程可以通过插桩来完成。覆盖分析工具提供有关功能覆盖、分支覆盖和条件覆盖信息。对于嵌入式软件来说,代码覆盖分析工具可能侵入代码执行过程,影响实时代码运行。
按照软件产品“先编程后焊接”和“先焊接后编程”两种生产顺序,嵌入式软件的固化方法分为两种:采用编程器(如ALL-11)离线编程的方法进行软件固化,采用在线编程(仿真环境、监控软件、交叉调试)的方法进行软件固化。
对于不具备在线固化条件的表贴芯片,需在芯片焊接到板卡之前,由设计人员从产品库中提取目标码文件进行固化,采用编程器(如ALL-11)进行离线烧写固化。先编程后焊接采用的编程器具有支持芯片厂家、覆盖面较广、人机交互界面友好、功能完善(提供了文件上传和下载、芯片擦除、编程、校验、数据比较)、固化可靠性强等优点,操作人员可利用编程器在离线模式下安全可靠地固化软件。由于在对产品进行开盖和换芯片处理后才能采用编程工具进行离线编程,因此“先编程后焊接”的方法不利于产品的后期维护,一般在生产阶段使用。
对于支持集成仿真调试环境和在线编程的产品,操作人员首先将JTAG/MPSD专用插头接到目标板的专用插座上,在主机和目标机建立通讯后,在仿真器的集成调试环境下,操作人员可以利用部分芯片的集成开发环境提供的编程工具或软件人员编写的专用固化程序进行软件目标码的在线固化。在对产品进行开盖后才能在仿真器的集成调试环境下进行在线编程,因此“仿真环境”编程的方法不利于产品的后期维护,一般在产品调试阶段使用。
产品监控软件是为产品研制的专用在线烧写软件,操作人员根据产品的具体特点,采用编程器/仿真环境固化的方法将产品监控软件的目标码烧写到芯片内部的指定空间,确保产品上电后处理器首先运行的是监控软件。
利用产品的专用接口电缆在产品和主机监控软件之间建立通讯关系,一般通过串口、1553B接口、USB接口、以太网等接口交互命令信息和数据信息,在产品不开盖的条件下,实现产品软件的在线更新和监控软件的自更新功能。自主开发的主机监控软件可在产品不开盖条件下进行软件在线固化,很大程度上提高了产品的可维护性,一般在产品的维护阶段使用。
对于运行在嵌入式操作系统VxWorks中的软件,由于嵌入式操作系统安装在CF卡/CFast卡/SATA硬盘中,固化该类软件产品时只需软件开发人员在Tornado/WorkBench下编译完的软件的*.o或者*.out文件拷贝到CF卡/CFast卡/SATA硬盘中即可。当VxWorks操作系统启动后,系统自动加载并执行*.o或者*.out文件,即可运行该嵌入式软件。
3.1.1 仿真环境
在仿真器配套提供的集成仿真环境下,调试过程需要注意以下事项:建议在加载程序运行前,先将CPU进行软复位,以确保CPU在初始态;在软件加载完成运行后,不要在Watch Window窗口频繁刷新相关变量的值,否则会导致程序中断异常,建议在程序进入断点后再观察变量和寄存器的值;频繁调用“printf语句”将会导致中断丢失。
3.1.2 监控环境
不同软件产品的RAM地址分配不尽相同,软件设计人员必须了解监控软件占用的RAM地址空间。在软件产品的CMD文件进行地址空间分配时进行充分考虑,否则会引起地址冲突,导致不可预知的运行结果。
3.1.3 黑盒环境
黑盒环境下通常采用软件源代码插桩的方式调试软件,通过在源代码中增加“调试代码”来监控软件的执行状态。
3.1.3.1 分析产品硬件系统,确认调试接口
可利用硬件产品的备用RS-422/RS-232串口作为调试接口和测试设备自带的串口接口连接,测试设备端用“串口调试助手”接收调试信息;若硬件产品没有备用RS-422/RS-232串口,可依据产品的实际接口配置,将产品的RS-422串口、开关量输出接口或DA输出接口作为调试接口和专用测试设备的相关接口连接,并在测试设备软件中编写“接收调试”的代码。
3.1.3.2 在产品软件源代码中进行插桩调试
不建议在源码编写完成、目标码固化后直接进行软件调试,应按照先简后繁的顺序分别进行调试;在源代码中进行插桩,应针对每个条件分支输出不同的监控信息。
3.1.4 交叉链接环境
3.1.4.1 任务监控
在VxWorks操作系统中使用taskIdListGet()函数可以获得当前操作系统中运行的所有任务,TaskStatusString获取任务状态名称,在发现任务出错时通过回调函数通知用户出错任务情况。
3.1.4.2 任务堆栈溢出
在VxWorks操作系统中通过taskInit()函数指定堆栈的内存地址到一块只读页的下方,然后运行taskActivate()函数,若有堆栈溢出,会出现MMU异常报错。此外还可通过checkStack()命令来检查任务的堆栈情况。
3.1.4.3 异常任务定位
在VxWorks操作系统任务执行过程中出现异常时,可通过执行函数tt()显示指定任务的函数调用关系,根据函数调用关系确定当前异常任务所处的位置,并查找异常原因。
在仿真环境下,建议软件人员在产品固化流程执行完成后,不要使固化程序的代码执行处于未知的状态,应加入空循环语句,断开仿真器连接,固化程序继续执行的情况下不会导致程序跑飞,出现不可预知的结果;在仿真器集成环境和监控软件进行软件固化时,应确保固化过程中不对产品进行断电操作,确保软件固化成功。
[1]李志丹.嵌入式软件调试方法研究[J].计算机与数字工程,2012,40(7):157-159.
[2]温平川,何先刚,殷茜.嵌入式软件调试器的设计与实现[J].西南师范大学学报(自然科学版),2003,28(2):209-213.
2095-6835(2020)10-0029-02
TP311.5
A
10.15913/j.cnki.kjycx.2020.10.011
林海(1976—),男,本科,海军装备部驻天津地区第二军事代表室工程师,主要从事装备质量监督与检验验收方面的工作。
〔编辑:严丽琴〕