实时嵌入式系统软件调试问题分析
本文将讨论常见的调试问题以及预防和检查这些故障问题的一些方法。
从历史角度上来看,嵌入式应用代码的调试流程可以分为两类。第一类调试流程是回答 “我的代码现在执行到哪里?” 的问题。当开发商依靠打印语句或者LED的闪烁来指示应用程序执行到某个节点的调试方法时,往往就属于这种情形。如果开发工具支持这种调试方法,可以沿着应用应当程序应当执行的路径插入断点。第二类调试流程是帮助回答“我看到的这一数值是从哪里来的?”这一问题。在这种情况下,人们往往依靠寄存器显示窗口观察变量信息、处理器内存的内容。人们还可以尝试单步执行,并且观察所有这些数据窗口以了解某个寄存器状态何时出现错误,内存位置何时得到错误的数据,抑或指针何时出现了误用。
当开发商写完全部代码后,如果无需了解网络基础设施,也没有操作系统的任务调度需要考虑,那么就可以利用这些调试方法使一个应用程序运行起来。然而,现在的情况并非如此。嵌入式处理器以超过600 MHz的速度运行,并且拥有可支持Ethernet和USB等协议的嵌入式外设,它们支持功能齐备的操作系统,例如uClinux,而且这些操作系统所调度的各种应用程序是由数千行代码构成。使用打印语句和利用LED来调试是不现实的,因为现在常常有如此之多的功能在执行是不可能的,或者它们会影响标准I/O口,从而造成处理器性能大幅度下降。
也可能发生这样的情况:处理器的工作速度是如此之快,以至于LED的亮灭速度会快到人眼无法察觉。另外现代的嵌入式系统通常支持断点的设定,但是伴随这些处理器所运行的代码数量,使得这种类型的断点调试难以驾驭。中断和多线程系统在代码的任何一点上设置一个断点,可能都无法指示系统的正确状态。由于断点设置在物理内存的某个地址上,索引不必了解线程的状态。如果使用寄存器显示方法,那么局部变量窗口和内存窗口都将有助于隔离出所载入的不恰当的量值,但是,由于这些是静态化的工具,不能给出有意义的运行中的调试信息,其适用性也常常很有限。
实时嵌入式系统软件最常见的调试问题可以大致划分为如下几类:
1. 同步问题
2. 内存和寄存器讹误(corruption)
3. 与中断相关的问题
4. 硬件配置问题
5. 异常情况
同步问题
在任何系统中,只要有多串序线程或者进程都在运行,而且是异步共享数据,则系统必然存在同步问题。对于共享数据的全部操作必须是原子化的,也就是说,只有在一个线程或者进程完成对数据的操作后,其它的线程才能对数据进行操作。
以图1为例,线程A和线程B对共享变量“counter”进行操作,A让counter 增加,而B则让counter减少。下方示出了线程A的counter++和线程B counter—的汇编代码。假设线程B的优先级要高于线程A,而线程A目前正在运行,则线程B将被阻止。
举例来说,假设初始的计数值是2,而线程A是执行线程。则线程A读入计数值,并送入一个寄存器,在使其增加一个增量后,再将其写回计数器变量上。
在可抢先的多线程系统中,高优先级的线程的执行可以抢先于低优先级的线程。例如,假定线程A执行Reg1 = Reg1+1指令后,一个事件唤醒线程B。此时,Reg1储存量值3。现在线程B被唤醒(正如蓝线所标示的那样),并读入计数器的量值2(它尚未被线程A刷新)并将其量值减小到1。正如棕色的线所显示的那样,经过一段时间,线程A恢复运行,将Reg1写入计数器中,而该计数器的储存量值为3。 在这个过程中,线程B的减量操作结果被丢弃。计数器存储的量值变为2,即线程A进行一次增量后,线程B又进行了一次减量操作。被窜改的链接表则是另一个例子。如果数据被一个线程和中断例程共享,则也会出现上面的问题,因为中断的执行与线程的执行之间是异步关系。
同步化方面的问题常常是很难进行调试的,因为它们取决于时序,是随着软件对数据的操作而随机出现的。幸运的是,这些问题可以通过恰当地保护任何共享数据来避免。大多数的实时操作系统可以提供同步化原语。开发商 可以使用最适当的机制来保护共享数据,而不至于影响系统的性能。如果数据在多个线程之间共享,则开发商将有如下的选择:
a. 关闭调度器以便当前的线程永远不会被其它线程抢先。(无调度区)
b. 使用信号两(Semaphore)或者互斥信号量(Mutex)来保护共享数据。
c. 利用关键区域来进行保护,即屏蔽所有的中断。
开发商必须从性能出发来选择恰当的技术选项。关闭调度器,将防止任何一种环境的切换,从而使得现在的线程能继续执行,直到调度器重新打开为止。这种方法有一个负面的影响:它将阻止任何
- 嵌入式系统的VxWorks安全性问题研究(11-06)
- DSP编程过程中的几个关键问题的研究(06-05)
- 教你构造一个51单片机的实时操作系统(08-22)
- DSP开发中值得注意的问题(02-16)
- 基于DSP编程的几个关键问题(03-26)
- 调试前的组网故障问题总结(12-19)