使用ADS+HJTAG调试Boot Loader

来源:互联网 发布:电池修复软件 编辑:程序博客网 时间:2024/04/30 11:08

嵌入式系统的Boot Loader相当于PC机的BIOS,通常我们在移植Boot Loader的时候,往往会陷入无任何软件工具可用的情况,甚至连串口都无法输出任何信息,要追查错误是非常困难的,这时候往往就需要JTAG接口协助我们进行调试了。

 

JTAG是联合测试工作组的简称,发展于1985年,作为一种简单的电路接口协议,一般用于访问IC内部的子模块,因此也常用于嵌入式系统的调试,目前大部分CPU都支持JTAG接口。

 

JTAG接口定义了5个引脚:

  1. TDI (测试数据输入)
  2. TDO (测试数据输出)
  3. TCK (测试时钟,一般工作在10-100MHz)
  4. TMS (测试模式选择)
  5. TRST (测试复位,可选)

通过TMS信号选择,一个JTAG接口可以串行的访问一块电路板上的所有IC。

 

由于并口带锁存的特点,我们可以自己做一根JTAG连接线,一头接在PC机的并口,另一头接嵌入式系统的JTAG接口,这样就可以使用PC机通过JTAG接口调试嵌入式系统了。

 

下面是并口JTAG连接线的参考电路图:

 

有了连接线,可以使用HJTAG来检测是否正确连接。这里最重要的是确保信号线在软硬件上定义一致,下面是我在HJTAG中使用的信号线定义:

 

如果定义一致,那么选Detect Target应能立即检测到设备,比如我连接到三星S3C2440,会立即检测到此IC定义的ID(下面以此MCU为例子):

 

 

如果确定线序定义是正确的,但仍无法检测到IC,那很有可能是并口连接线的问题,换一根尽量短的并口连接线再试试可能就成功了。

 

 

HJTAG正确连接之后,可以使用ADS的工具AXD Debugger进行调试。使用之前,需要先设置调试目标,可以打开菜单Options->Configure Target...,点击Add,加入HJTAG目录下的H-JTAG.dll:

 

点击OK后,可以看到左边Target列表中增加了我们的JTAG设备。

 

对于ADS编译的Boot Loader,一般会生成两个文件,后缀名为bin的,是可以写入Flash的二进制文件,而后缀名为axf的,是可以作为镜像载入调试器,进行源代码级的调试。

 

 

如上图,可以看到载入Boot Loader axf镜像文件后,CPU自动定位到文件指定的启动位置,可以看到地址为0x00000000,系统启动后第一条指令即调用ResetHandler的过程。这里的过程名叫ResetHandler是有名堂的,嵌入式系统一般要求功耗较低,所以S3C2440是支持休眠模式的,当进入休眠模式后,CPU会被掉电关闭,内存进入自刷新模式,整颗IC仅有少数几个中断处于工作状态,这时候的功耗是很低的。当中断触发后CPU被重新唤醒时,CPU重新上电,PC指向地址0x00000000,意味着无论休眠之前系统跑的是Linux还是WinCE也好,这时候都只会从Boot Loader重新运行,为了能快速返回操作系统睡眠之前的状态,而不是重新重复冷启动的漫长过程,比如载入OS到内存中,初始化硬件,等等...,系统休眠之前会在内存中保存需要返回的地址,并设置状态寄存器,Boot Loader在启动后,会读出状态寄存器的值,如果确定CPU的关闭是由于休眠引起,那么就在完成设置MMU等必要初始化过程后,直接跳到休眠之前保存的指令地址,完成快速唤醒的动作。CPU上电,对于Boot Loader也只是一次Reset而已,无非是冷启动和热启动的区别,所以这第一条指令顺理成章的被命名为ResetHandler。实现S3C2440的休眠和唤醒,关键即在于Boot Loader和操作系统之间的配合。

 

如果我们的Boot Loader不是ADS编译的,那调试起来就要麻烦一点了,首先是无法进行源代码级调试,但这问题不大,启动代码也是汇编写的,基本可以自己对着源代码一行行往下看。

 

比如我们要调试arm-linux-gcc编译的vivi,可以这么操作,首先将vivi的二进制文件载入内存0x00000000,然后自己将寄存器PC设置为0x00000000,然后会惊喜的发现,代码正在等着我们运行呢。

 

原创粉丝点击