首先需要介绍一下GDB调试接口的RSP协议中的几个命令:
1."Maddr,size:data"为写memory,地址addr,长度为size,data为数据。
例如:"M8ec,4:55aacc33"指,在0x000008ec的地址上,写4个字节数据:0x55aacc33。
2."maddr,size"为读数据,注意这里的大小写,后面也会碰到。
3."g"为列出所有寄存器
4."c"为继续执行
5."s"为单步执行
6."Z1,addr,size"为设置硬件断点,地址为addr,大小为size(ARM模式下为4,Thumb模式下为2)。
7."z1,addr,size"为擦除硬件断点,参数同上
问题出在IAR处理switch指令的时候,IAR处理单步switch指令会使用"s"命令来执行到应该停止的位置,但有时,IAR会秀逗到处理错这个应该到的地址,这样会一直调用"s"命令,直到异常或者其他中断或者到IAR处理错的那个地址。
OpenOCD测试命令:
openocd -d3 -f interface\olink.cfg -f target\lpc2148.cfg -f script\lpc2148_debug_iar.cfg 2>&1 | grep "gdb_input_inner(): received packet: "
其中,2>&1是把stderr的信息连接到stdout,这样就可以用grep命令来过滤数据了,不明白的自己去补充(我在Windows下安装了Linux的基本命令包,所以可以直接运行)。
比如:
这段代码是IAR EWARM5.11 KS自带的2148的demo程序中的代码。这个时候,OpenOCD输出的信息是(最后部分):
到这里都没有问题,这里如果按下C语言的单步执行命令的话,应该执行到PLLCFG_bit.PSEL = 0x2;,也就是需要执行7个"s"指令(从目前的位置0x00000210到0x00000228,执行了ADD PC, PC, R1, LSL #2之后就可以跳转到应该停止的地址了),但是结果是(注意输出信息的序号):
后面还省略了几页。IAR会执行一个"s",之后执行"g"来查看寄存器内容。结果就是一直执行到下一处中断为止,并且由于使用的是汇编的单步执行指令,所以速度非常慢。
产生原因分析:可能是由于IAR在计算C语言中的一个step指令运行之后,程序应该停止在的地址出错,使得调试器一直调用汇编的单步调试命令,直到遇到其他中断。IAR没有bug report的maillist,所以也无法回报这个bug。
这个Bug如何解决?
临时的解决方法:保证至少有一个硬件中断可以使用(ARM7核有2个硬件中断),遇到switch指令时,现在switch指令后面设置断点,然后再运行,到了断点位置后再取消这个断点。
用户131114 2008-12-14 16:50
用户75050 2008-12-5 09:08