安全苛求系统下的嵌入式C语言程序调试技巧
2014-02-11董高云周庭梁
董高云,周庭梁
(1.卡斯柯信号有限公司 研发中心, 上海 200071;2.同济大学 道路与交通工程教育部重点实验室,上海 201804)
安全苛求系统下的嵌入式C语言程序调试技巧
董高云1,周庭梁2
(1.卡斯柯信号有限公司 研发中心, 上海 200071;2.同济大学 道路与交通工程教育部重点实验室,上海 201804)
介绍安全苛求系统下的嵌入式C语言程序调试的技巧。总结安全苛求系统的编码和程序调试工作中的嵌入式C语言调试经验,介绍正式代码调试之前的3件准备工作,代码调试的“版本升级比较法”,打印添加技巧以及其它调试技巧和经验。
安全苛求系统;嵌入式系统; C语言;调试技巧
安全苛求系统(Safety Critical System),通常是指一旦发生故障或出现差错,会带来人员伤亡、大宗财产损失、环境遭受严重破坏的系统[1]。安全苛求系统多以计算机为核心子系统构成其监控系统,这类系统又被称为安全苛求计算机系统,国内有的文献也称之为“安全关键计算机系统”。安全苛求计算机系统常用于军事、航空航天、工业控制、银行、医疗、通信等安全苛求领域,以避免由于计算机的失效造成重大事故。在铁路信号领域的安全苛求系统包括车站联锁、区间闭塞,列车自动驾驶,列车超速防护和道口防护等。
对于安全苛求系统,需要从系统的规划阶段开始,在整个生命周期中给予特殊的关注。它的需求说明、设计、制作、验证、安装、使用维护等都有特殊的要求。除了需要利用一系列的容错技术保证系统的可靠性以外,还需要采用故障–安全的技术来防护系统在故障或者软件错误的情况下产生灾难性的后果。例如在铁路信号领域的联锁系统中经常采用的二乘二取二结构。
为了满足安全苛求系统故障-安全的需要,高实时性、多任务的嵌入式操作成为首选。该系统广泛应用于铁路信号领域的联锁、列车控制车、载控制器(CC)、轨旁区域控制器/线路控制器(ZC/LC)等多个安全产品中。因此,掌握在嵌入式操作系统环境下的程序开发调试技巧,是从事相关工作的技术人员的迫切需要。
1 正式进行代码调试之前的准备
安全苛求系统下的嵌入式程序故障表现为系统运行不稳定,或部分功能实现不正确,其原因大致可以分为以下几类:硬件故障;驱动板级支持包(BSP)和操作系统的故障;配置文件错误;软件本身的漏洞(BUG)。
正确的代码调试步骤,应该是在确认和定位程序代码的BUG之前,首先要排除前3类原因,然后再展开代码本身的调试,也就是正式开始进行嵌入式操作系统程序代码BUG调试之前所必须要做的3件事情。
(1)先排除硬件故障的可能。嵌入式系统本身是一个软硬件紧密结合的系统,很多从表现上看是软件的故障,实际查下来才发现是硬件所导致的。主要的硬件故障包括板卡本身的损坏和故障,板卡接触不良,硬件插错等。此外,用于网络通信的交换机和集线器本身的故障,也会造成网络通信的不正常,或者进行嵌入式程序调试时下载缓慢等。只有先排除了以上的各种硬件故障之后,再继续下面的排查。
排除硬件的一个简单方法是:在备件充足的情况下,通过交换硬件来进行硬件故障的确认。例如互为主备的联锁A机机柜故障,联锁B机机柜运行正常,若怀疑A机的某块硬件板卡有问题,则与B机交换对等的硬件板卡,观察故障是否跟着板卡走(即交换后,A机变为正常,B机变成故障),如果是的话,应该就是该块硬件板卡的问题。
(2)确认驱动程序和BSP包是否正常。在代码调试时,除非进行新产品开发,相关驱动尚未发布,否则必须选用已正式发布的驱动。在嵌入式系统调试过程中,经常会碰到由于硬件的驱动本身有BUG,导致通信有故障或通信功能不稳定的情况发生,此时如果贸然排查上层软件的话,很可能走错了查找的方向。
此外,已发布的驱动只是针对该驱动发布时的硬件和BSP包环境所进行的封版测试,并不一定能保证在所有的硬件和BSP包环境下的正常运行。为了定位是否为驱动本身的问题,在求助于驱动开发人员之前,调试人员需要先准备好一个驱动测试程序,该测试程序只保留与驱动相关的部分代码,从而将问题定位至驱动本身,证明问题来源于驱动,也方便驱动开发人员进行驱动问题排查。
还有编译环境的问题,调试某个版本的代码时始终只有单网通信,无法实现双网冗余,排查了所有原因,最终发现是进行调试所用的笔记本电脑所装载的Tornado开发环境软件包本身有问题,导致编译后的可执行文件有缺陷。重装Tornado后再进行编译,故障就没有再出现了。
(3)确认所调试程序的配置文件是正确无误的,且各个配置文件都是基于同一版本发布基线的。在正式的程序调试之前,一定要确认该代码相关的所有配置文件版本无误,且是相互匹配的,在一个错误配置环境下的所有“故障”现象,由于其本身配置的不正常,都无法作为程序本身“故障”的参考。
2 版本升级对比法
版本升级对比法的具体操作为:在查找问题前,首先确保有一份旧版本且确认无BUG的代码,对新旧版本的代码展开对比调试。即:采用代码比较软件(如Beyond Compare),逐行对比新旧版本代码。基于一个基本的出发点:新版本的代码BUG是在旧版本的基础上,进行升级过程中所引入的。
对于引起BUG的故障语句的定位,可以有两种思路:添加法,即在旧代码的基础上,逐步添加升级代码,每次只添加一个或两个功能点的升级代码,每添加完后进行编译运行,观察是否异常,一般情况下,在添加至某个功能点时,会出现“故障”现象,则可以定位为添加的功能点相关代码是引起“故障”的源头,从而实现“故障”代码的定位。减少法,在新代码的基础上逐步删减功能点,退回至稳定版本的旧代码,在此过程中,会有某一功能点的减少,导致原来不稳定的代码重新趋于稳定,这个功能点相关的代码就是引起新代码不稳定的“故障”代码源头。
当然,无论是添加法还是减少法,都需要提前规划测试策略,注意做好测试版本的备份。在调试过程中,需要注意编译环境的问题,注意全编译和部分编译的区别。每次“添加”或“删减”一个功能点之后,进行运行拷机之前,最好要进行全编译,以确保完全整合了所有的修改,保证编译代码的完整性。
3 面向接口的调试方法
进行嵌入式系统调试时,需要注意使用打印语句进行变量追踪。由于嵌入式实时程序的特殊性,在非嵌入式(如Visual C++)程序调试时所使用的单步调试,加断点、变量和语句的跟踪等方法在大多数情况下无法使用。对于vxWorks这样的操作系统,只能通过添加打印语句来实现。打印语句的添加需要注意两点:(1)在中断中,不能添加printf打印语句,只能添加logMsg()函数的打印语句。(2)无论是添加printf语句,还是添加logMsg(),都需要“慎用”,要考虑到这两种打印语句对系统的稳定性所带来的负面影响。
通过添加临时全局变量的方式,实际上是“面向接口的调试方法”的一种,即增加专用的调试接口,以方便故障定位和程序调试。除了增加临时变量的方式,还可以采用直接增加网络消息处理函数,将相关的调试信息通过网络接口直接发送到上位机的诊断维护支持系统中,从而使在线诊断和故障分析更加方便。与临时添加打印变量相比,采用诊断维护支持系统来获取调试信息的方式,能够实现调试信息的在线实时存储,有利于实现长时间拷机时的故障记录,对于出现频率低的故障收集和排查具有良好的效果。
4 其它调试技巧和经验
除了以上的调试技巧之外,还需要强调的是从事嵌入式系统调试的相关人员,需要有一个良好的心态。嵌入式系统运行和启动比较耗时,每次重启之后,宿主机需要重新连接下位目标机。从事安全系统和安全软件开发的技术人员都有一个基本理念,就是计算机本身可能受到随机干扰的影响会出错,所以才会引出安全计算机的概念。但是需要指出,在嵌入式代码调试时,恰恰要反过来,不能夸大随机干扰的影响。需要将系统性故障和随机故障区分开,因为本身程序的BUG而引入的故障均为系统性故障,与CPU或RAM等随机出错引起的随机性故障无关,相应的出错概率也远高于随机故障的出错概率。
在问题查找过程中,除了采用打印跟踪之外,还可以考虑利用其它开发环境所提供的交互工具对嵌入式程序的运行进行监控,对程序架构和代码中的关键变量,任务执行等进行分析。
5 结束语
对于短期内难以解决的疑难问题,必须坚持长期拷机,持续跟进测试,并定期发布拷机汇报,做好拷机记录,不放过任何细节,嵌入式系统的调试人员只有抱着持之以衡的心态,采取正确的策略,理清相关的思路,才能攻坚克难获得最终胜利。
[1]郦 萌, 吴芳美. 铁路信号可靠性安全性理论及证实[M].北京:中国铁道出版社, 2008.
[2]员春欣, 江建慧. 安全关键计算机系统[M]. 北京:中国铁道出版社, 2003.
[3]邝 坚. Tornado/VxWorks 入门与提高[M]. 北京:科学出版社,2004.
[4]Wind River. VxWorks/BSP 开发人员指南[M]. 王金刚,苏 琪,杨锡劢,译.北京:清华大学出版社,2003.
责任编辑 陈 蓉
Program debug skill of C Language in Embedded Operation System running in Safety Critical System
DONG Gaoyun1, ZHOU Tingliang2
( 1. Research and Development Center, CASCO Signal Company, Shanghai 200071, China; 2. Key Laboratory of Road and Traff i c Engineering of the State Ministry of Education, Tongji University, Shanghai 201804, China )
This paper introduced the program debug skills of C Language in Embedded Operation System running in Safety Critical System, summarized serials of debug experiences of C Language. The three preparing work was pointed out before formal code debugging. The “version updating &comparing method”was introduced. The print adding skills during debug process and other debug skills as well as the experiences for Safety Critical System were also introduced.
Safety Critical System; Embedded Operation System; C Language; debug skills
U284∶TP39
:A
1005-8451(2014)06-0062-03
2014-01-28
董高云 ,高级工程师;周庭梁,在读博士研究生。