使用使用gdb调试嵌入式系统调试嵌入式系统
1. 概论
我们将学习使用gdb来调试通过一个通过串行线同PC相连的嵌入式系统.
Gdb可以调试各种程序,包括C、C++、JAVA、PASCAL、FORAN和一些其它的语言。包括GNU所支持的所有微处理器的
汇编语言。
在gdb的所有可圈可点的特性中,有一点值得注意,就是当运行gdb的平台(宿主机)通过串行端口(或网络连接,或是其
他别的方式)连接到目标板时(应用程序在板上运行 ),gdb 可以调试对应用程序进行调试。这个特性不光在将GNU工具移
植到一个新的操作 系统或微处理器时侯很有用,对于那些使用GNU已经支持的芯片的嵌入式系统进行开发的 设计人员来讲,
也是非常有用的。
当gdb被适当的集成到某个嵌入式系统中的时候,它的远程调试功能允许设计人员一 步一步的调试程序代码、设置断点、
检验内存,并且同目标交换信息。Gdb同目标板交换 信息的能力相当强,胜过绝大多数的商业调试内核,甚至功能相当于某
些低端仿真器。
2. Gdb在嵌入式领域的功能实现
当调试一个远端目标设备时,gdb依*了一个调试stub来完成其功能。调试stub即是 嵌入式系统中一小段代码,它提供了运
行gdb的宿主机和所调试的应用程序间的一个媒介。
Gdb和调试stub通过GDB串行协议进行通信。GDB串行协议是一种基于消息的ASCII码 协议,包含了诸如读写内存、查询
寄存器、运行程序等命令。由于绝大多数嵌入式系统 设计人员为了最好的利用他们手中特定的硬件的特征,总是自己编写自
己的stub。所以 我们有必要清楚的了解一下gdb的串行通信协议。在后面我们会详细介绍。
为了设置断点,gdb使用内存读写命令,来无损害地将原指令用一个TRAP命令或其它 类似的操作码(在此假定,被调试的
应用程序是处在RAM中的,当然,如果stub有足够好 的性能,硬件也不错的话,这个条件也不是必须的)代替,使得执行该
命令时,可以使 得控制权转移到调试stub手中去。在此时,调试stub的任务就是将当前场景传送给gdb (通过远程串行通信协
议),然后从gdb处接收命令,该命令告诉了stub下一步该做什么。
为了说明,下面的代码是Hitachi SH-2处理器的一个TRAP异常处理程序:
/*将当前寄存器的值存储到堆栈中*/
/* 然后调用gdb_exception. */
asm("
.global _gdb_exception_32
_gdb_exception_32:
/* 将堆栈指针和r14压入堆栈*/
mov.l r15, @-r15
mov.l r14, @-r15
/*当执行一个陷阱异常时,sh2 自动的将pc 和sr 放入堆栈 */
/*所以我们必须调整我们给gdb的堆栈指针值,以此来说明这个特别的数据 */
/* 换言之,在该陷阱被执行前,gdb想看看堆栈指针的值,*/
/* 而不是陷阱被执行当前时的值。*/
/*所以,从我们刚压入堆栈的sp值中减去8*/
/*(pc和sr都是4个字节的 )*/
mov.l @(4,r15), r14
add #8, r14
mov.l r14, @(4,r15)
/*将其它寄存器值压入堆栈 */
mov.l r13, @-r15
mov.l r12, @-r15
mov.l r11, @-r15
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
mov.l r7, @-r15
mov.l r6, @-r15
mov.l r5, @-r15
mov.l r4, @-r15
mov.l r3, @-r15
mov.l r2, @-r15
mov.l r1, @-r15
mov.l r0, @-r15
sts.l macl, @-r15
sts.l mach, @-r15