1:嵌入式系统调试
总体上说嵌入式系统,特别是基于SOC设计的ARM,利用自由和开源软件作为嵌入式开发工具的一个完整部分在过去的几年内有很大的发展。一项由
linuxdevices.com进行的调查表明43%的调查者使用嵌入式Linux在他们或者他们的公司产品中,另外55%
会在接下来的两年中使用。设计中使用最多的是ARM处理器结构,在开发中占30%,其次占28%的x86。开源工具被59%的调查者作为第一选择,82%的调查者认为这些工具对于开发嵌入式Linux是很好的是可以接受的。
自由和开源项目为ARM开发提供了一套高质量的开发工具链,然而却缺乏调试的支持,特别是涉及到系统编程的时候。GNU调试器(gdb)提供了完美的调试支持,但是仅仅包含了嵌入式系统调试的某一些部分。底层的任务需要硬件的支持,现有的开源解决方案对此类任务是无能为力的,至少是有些不完善的。
这个毕业设计的目标就是设计和实现一个自由的针对ARM7和ARM9系列的调试解决方案,使得昂贵的商业工具没有市场。作为工作一部分所写出来的这个软件开始只支持处理器系列中的某几种,但是通过适当的设计可以使得扩展很容易。目标接口应该基于IEEE标准测试访问端口和边界扫描结构。支持不同的PC主机和IEEE
1149.1兼容目标的接口是一个十分明确的目标。
嵌入式系统的调试和传统的应用程序调试在许多方面都是不同的。相对于桌面系统,嵌入式系统有更少的资源,比如主存,处理器能力,或者输入输出能力。这就使得在一个系统上运行软件调试程序和被调试的程序就不不方便甚至是不可能的。取决于开发的任务,有可能在目标系统上根本就没有一点运行的软件,比如Bootloader的开发。在这种情况下,系统上通常也没有调试器。在应用程序的开发过程中,我们期望硬件是不出现错误的,也就是所有的子系统(CPU
,memory,storage,I/O)是可工作的。在嵌入式系统中,硬件是可能出错的,比如一个不稳定的内存接口或者一个未测试的系统组件。加入内存系统失效或者未测试,任何代码可能出错,哪怕是一个调试器。
由于这些限制,嵌入式系统经常利用远程调试器进行调试:调试器运行在一个主机上,然后通过硬件或者一个运行在目标系统上的小软件控制目标系统。这样开发者就有可能利用他的工作站提供的所有功能,而目标系统没有必要运行一个全功能的调试器。
调试的目的是分辨和移除软件程序中的缺陷。可以通过被动的看代码,或者是数据流,也可以主动的将目标停在某个重要的点来达到上述目的。被动调试有不被打断,可以让程序顺序地被检测的优点。而主动调试可以让开发者控制程序流,或者改变目标内存的内容。
几年前,嵌入式系统不得不利用其他的程序将程序代码下载到内存芯片中。这个芯片从目标系统中分离出来,编程,再放回到目标系统中。现在可以通过在目标系统上运行一个非常简单的嵌入式开发工具来下载程序代码到目标系统中。
接下来的几部分列出了一些通用的嵌入式调试解决方案,也看一下实际中目前可用的ARM7/ARM9的调试解决方案。给出了一个嵌入式系统设计,调试的细节性评价。
1.1 调试解决方案
逻辑分析仪,硬件跟踪
逻辑分析仪和专门的跟踪硬件,像 ARM embedded trace
macrocell
(ETM) 允许程序流被动的被观测。逻辑分析仪观测目标的数据和地址总线,通常给出执行指令的一个列表,可能有访问数据的注释。而对于一些老的微控制器,由于每次指令的执行都导致内存系统的访问,所有没办法利用现代缓存结构来跟踪程序的执行。包括进入缓存的指令不会在内存接口上表现出来,所有使得完整的跟踪是不可能的。独立的跟踪硬件是和微控制器内核紧密结合的,使每条执行的指令路径都不依赖于内存接口。在高速时钟下,系统产生的自然数据增长的非常快,这样就很难从目标系统中得到信息,也很难找到相应的部分。高级解决方案比如ETM9允许触发点,比如指令地址在跟踪硬件开始监视内核的时候就被定义。过滤器进一步限制了从内核传送到调试主机的数据量。
ICE仿真,ROM仿真
ICE使用一种特殊的调试变量取代目标微控制器,它包含一个硬件调试工具。仿真器连接一个运行调试软件的主机。允许被动和主动调试,给出一个不中断的程序流的视图,允许对程序执行,CPU状态和内存内容很好的控制。ROM仿真器利用双端口随机访问内存模块取代目标系统非易失性内存。这样就能被调试器和目标系统同时访问。在不得不从ROM开始执行代码的地方,就可以允许调试器利用必要的获取调试入口的挂钩来替换指令,比如TRAP或者失软中断(SWI)指令。代码测试改进了,因为内存芯片不需要额外的工具来编程。ICE可能支持硬件断点,在该处地址比较器始终监视地址总线,当取得的指令地址符合的时候就强制系统进入调试状态。这就可以不使用ROM仿真器而在ROM中的代码上设置断点。如果ICE更进一步支持覆载内存,就可能下载代码到目标系统中,替换在ROM区域中的指令。ICE观测可访问内存空间,当覆载内存发生时就跳转到RAM.。
调试桩
调试桩,通常被称为“调试代理”,运行在目标系统中,连接到运行调试软件的主机。他们需要初始化代码,设置调试时钟,主内存,和通信渠道。这就使得调试桩在早期的开发中不适用,初始化的代码需要被调试。
调试桩利用目标系统的中断来控制程序的执行,比如使用串口中断向量的时候就会用到RS232通信。当主机调试器发送数据到调试桩时,中断就发生,让桩控制整个目标系统。桩就使用同种类的TRAP
或者 BREAKPOINT
指令,或者SWI指令来替换断点指令。一旦目标系统触发了一个断点指令,控制权就交给了调试桩,它能将断点信息返回给调试主机。
调试桩的主要缺点是要初始化和时候目标系统的资源,但是它们只需要一点额外的硬件,使得对开发工具成本要求很严格的就很有吸引力。
集成调试电路,片上调试
集成调试电路使得ICE仿真器在高适应性上有很强的能力。相对于使用特殊的调试版本替换目标微控制器,每个出售的芯片上都有调试功能。使用少量的连接针脚,串口通信通道使用连接到调试主机的调试电路就能达到高速的操作。
ARM调试方案
因为基于ARM7和ARM9系列的片上系统设计的流行,好些供应商提供所有的ARM7
和ARM9
微控制器的集成调试电路。相对于商业工具,也有自由和开源的实现,提供很大范围的支持功能。有些作为混合方案提供,主机PC和调试目标之间的接口硬件通过调试软件实现连接,有些是纯硬件的解决方案,能够和各种软件产品配合使用。这里,测试软件没有必要是一个全功能调试器,而是一个和硬件通信,为调试前端提供一组调试功能的软件。下面不是一个很容易理解的列表,而是展示一下典型的设计。
硬件和软件混合解决方案
ARM Multi-ICE
http://www.arm.com/products/DevTools/MultiICE.html ARM Multi-ICE 支持各种不同的ARM
内核,提供尽可能的功能,包括访问特殊系统控制寄存器,FLASH
烧写。通过PC并口连接主机,通过达到10MHZ的JTAG时钟访问目标系统。配套使用的软件叫Multi-ICE
sever,它包含目标特殊调试功能,为调试前端提供远程调试接口。Multi-ICE
sever 需要PC 机运行Microsoft windows 。不支持Linux
和其他的自由操作系统。
ARM RealView RVI
http://www.arm.com/products/DevTools/RVI.html ARM RealView ICE
取代Multi-ICE,提供高达50MHZ的JTAG时钟,更长的电缆,使用USB连接主机,这样就提供了极大的灵活性。RVI包含一个处理所有目标系统特殊调试功能的ARM9处理器。需要RealView
Debugger 作为前端,可以在Microsoft Windows, Linux
和 Solaris 上使用。
Abatron BDI2000
http://www.abatron.ch/ BDI2000
通过RS232或者是10BASE-T以太网连接主机,支持16MHZ的JTAG时钟。硬件能针对各种目标系统进行配置,包括针对ARM7
和ARM9
目标配置。目标特殊调试功能包含在BDI2000中。被各种调试前端支持,比如ARM
RealView Tools ,Metroverks CodeWarrior
或者是GDB。一个附加的远程接口提供对特殊硬件调试功能的直接访问。BDI2000提供几乎所有的调试功能,包括系统控制寄存器。
硬件解决方案
Macraigor Wiggler, Parallel Port Wigglers
http://www.macraigor.com/wiggler.htm Macraigor Wiggler
是一个简易设备用来连接PC并口到目标的JTAG接口。主机PC
仿真目标接口靠切换信号开和关,是一种通常叫作
“bit-banging”
的技术。它表现像一个信号缓存,提供PC和目标系统间必要级别的转换。Wiggler兼容的克隆版的原理图在网上是可以自由获取的,可以修改适合特殊的需要,比如添加和移除JTAG标准中的某些信号。图1.1是一个完整的wiggler
克隆。Wiggler的速度由PC的并口速度决定,每条指令进或者出大概需要1微秒。一个完整的时钟周期至少需要2微秒,所以最高速度只能达到500KHZ。
Macraigor Raven
http://www.macraigor.com/raven.htm 和wiggler类似,Macraigor raven 通过PC
并口连接主机,但是它使用的是增强的并口协议和高级别命令。逻辑上
raven
内部将并口数据转换成高达8MHZ的串行流。Raven的内部设计是专有的,原理图是不能用的。在Microsoft
Windows和Linux下二进制设备是可用的。
Amontec Chameleon POD
http://www.amontec.com/chameleon.shtml Amontec Chameleon POD 基于Xilinx Coolrunner (XPLA3) XCR3128XL-VQ100
Complex
Programmable Logic Device (CPLD)
(
http://www.xilinx.com)。它通过PC的并口连接主机,支持许多不同的配置,包括
macraigor
wiggler和raven的仿真。配置可以免费下载,在windows下通过适当的软件烧写到chameleon中。
USBJTAG-1
这个设备由Hubert H?gl 设计,通过USB 1.1 全速接口连接PC
主机。FTDI芯片通过使用MPSSE,JTAG 时钟可以达到6MHZ 到
93 HZ.
图1.2是一个使用DLP-2232M的一个实现。
软件方案
Macraigor OCD Commander, OCDRemote
http://www.macraigor.com/ocd_cmd.htm,
http://www.macraigor.com/full_gnu.htm Macraigor 软件包与Macraigor Wiggler,Raven ,usbDemon 和mpDemon
设备一起使用,但是也可以使用自由软件协议与Wiggler和Raven的克隆一起使用。支持的核包括
ARM7 ARM9成员,MIPS, MOTOROLA POWERPC ,INTEL
XSCALE。不能访问特殊寄存器。也每有扩展的cache和 MMU处理的信息。OCD
Commander 是一个完整的图形化的调试器,OCDRemote
是一个连接Macraigor 硬件和
GDB客户端的终端程序。两个都能在Microsoft windows
和Linux下使用。由于这个Linux版的只是一个链接到指定内核模块的二进制文件,所以就没有可能使用这个自由软件来烧写FLASH。但是Macraigor提供了一个叫“Flash
Programmer“的程序来提供ARM7 和ARM9 的Flash烧写。
开源软件
有几个开源的项目支持ARM7
和ARM9的调试,都是GPL版权。比起商业软件功能有不足,并且除了gdb-jtag-arm似乎都不在开发了。仅支持的JTAG硬件接口是Wiggler和兼容的。没有一个项目支持比如在ARM720t或者是ARM920t中的MMU处理或者caches。
JTAGER by Rongkai Zhan
http://jtager.sourceforge.net/ JTAGER支持ARM7TDMI,ARM720t和ARM920t
目标系统。对于ST39LF/VF160和MBM29LV650芯片支持FLASH
烧写。对用户实现了命令行接口,不支持GDB。2004年十月17号的Version0.3.0是稳定版,依旧处于早期开发阶段。代码的bugs和shortfalls可能导致目标系统的崩溃和内存的混乱。
armtool by Erwin Authried
http://home.at/cgi-bin/viewcvs.cgi/midori/sources/armtool/ armtool
仅支持基于ARM7TDMI的系统。可以写和读目标系统内存,可以将代码下载到目标系统中运行。它适合于批处理,不允许用户交互,没有命令行接口也没有使用调试前端。不支持FLASH烧写。
jtag-arm9 by Simon Wood
http://jtag-arm9.sourceforge.net/ jtag-arm9
仅支持基于 ARM9的系统。包含一个命令行供用户交互。能够停止和重启目标系统,读取和修改目标寄存器,支持内存读写操作。不支持FLASH。
gdb-jtag-arm by Tobias Lorenz
http://gdb-jtag-arm.sourceforge.net/ Gdb-jtag-arm
是唯一支持gdb作为调试前端的开源项目。它基于jtag-arm9
,修改了许多,但不是全部,原软件的bugs。由于这些缺陷可能导致在向目标系统内存写入的时候引起目标系统的崩溃。