因为WIGGLER的一些不可避免的缺点,我们现在将精力集中在JLink上。
JLink是大家都能够买的起的仿真器(当然是D版),已经是白菜价了,可以参考淘宝。他真的是仿真器,虽然目前只能支持ARM系列的芯片,和WIGGLER的区别是TCK的频率可以到12MHz,从逻辑分析仪上看到的情况是接近13MHz
基于JLink做2次开发,
可参考的资料有2个:
1. 官方的协议文档:RM08001_JLinkUSBProtocol.pdf
2. OpenOCD的代码openocd-0.4.0-rc1/src/jtag/drivers/jlink.c
首先在Cygwin的环境下编译最新的openocd的代码,具体的编译过程官方的网站上有详细的描述。
下面是我编译的Image的运行情况:
I:/Study/JTAG/bin>openocd -f jlink.cfg Open On-Chip Debugger 0.4.0-rc1 (2010-02-05-00:04) For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html Info : J-Link initialization started / target CPU reset initiated Info : J-Link ARM V7 compiled Apr 1 2009 12:02:10 Info : JLink caps 0x39ff7bbf Info : JLink hw version 70000 Info : JLink max mem block 9120 Info : Vref = 0.0 TCK = 1 TDI = 0 TDO = 0 TMS = 0 SRST = 1 TRST = 1
Error: Vref too low. Check Target Power
Info : J-Link JTAG Interface ready Error: jlink_usb_message failed with result=5) Error: jlink_tap_execute, wrong result -107 (expected 1) Info : RCLK (adaptive clock speed) Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!! Error: jlink_usb_message failed with result=5) Error: jlink_tap_execute, wrong result -107 (expected 1) Error: jlink_usb_message failed with result=5) Error: jlink_tap_execute, wrong result -107 (expected 1) Command handler execution failed Warn : jtag initialization failed; try 'jtag init' again. Warn : gdb services need one or more targets defined |
需要说明的是因为OpenOCD使用的是libusb的库,所以相应的JLink官方提供的驱动也就不能用了,下面这段也来自官方网站。
Gene Smith wrote: > I now get a successful build under cygwin. When I plug the jlink usb to > windows and run openocd I see the the "Cannot find jlink Interface!" > error as printed below. Do I need another special windows driver when > running jlink in cygwin? To build I only copied usb.h and libusb.a as > directed from libusb-win32 project. There is quite a bit of stuff in the > libusb-win32-device-bin.tar.gz that I haven't used. Should this be > installed? > Yes.
I had the segger jlink commander installed so its driver ran when I plugged in the jlink and didn't work with openocd. I had to replace it with the driver from libusb-win32-device-bin on sourceforge. (A "no driver found dialog" would have popped up if I didn't have segger installed already, I think.) Uninstalling segger jlink tools did not remove the segger driver. Had to go into Control Panel/System/Device Manager and update the jlink driver to point at the new jlink.inf file I had made with the libusb-win32/bin inf-wizard. Then I browsed to the actual unsigned driver pointed to by the inf, libusb0.dll from the libusb-win32-device-bin distribution to complete the installation. I did not try to use the "filter" driver which I think can coexist with the segger driver (according to a post by Xiaofan which seems to be the only mention of whether this 3rd party driver is really needed by openocd).
Note: the segger driver appeared under "Universal Serial Bus Controllers" in Device Manager (winXP) while the libusb-win32 driver appears as new top level Dev Mgr category "LibUSB-Win32 Devices".
-gene |
这样我们就具备了一个JLink的学习环境了。
OpenOCD主要精力在ARMx Technical Reference Manual里描述PRIVATE INSTRUCTION的使用,和调试命令的实现上,所以这里我只是用了openocd-0.4.0-rc1/src/jtag/drivers/jlink.c这个文件。
最需要了解的是2点:
1. JLink内部有3块Buffer,大小都是2048Bytes,用来存放TDI TMS和TDO的信号,其中每个信号的状态都是以Bit来存放的,所以最长可以支持到16384个TCK。
Jlink.c里的void jlink_tap_append_step(int tms, int tdi)函数就描述了如何填充TDI TMS buffer的。
2. 就是USB通信命令里的EMU_CMD_HW_JTAG3,因为的确很重要我把他们从RM08001_JLinkUSBProtocol.pdf里复制出来。
Jlink.c里的int jlink_tap_execute(void)函数就描述了这个命令执行的过程。
EMU_CMD_HW_JTAG3
Description
Handles the JTAG connection. It receives data for TDI and TMS and sends TDO data
back.
Command
Direction Data Name Explanation
H->E 1 * U8 Cmd Command: 0xCF
H->E 1 * U8 DUMMY Dummy data in order to word align data transfers.
H->E 1 * U16 NumBits Number of bits to transfer.
H->E <NumBytes>* U8 TMS Data for TMS. NumBytes calculates as follows: NumBytes = (NumBits + 7) >> 3
H->E <NumBytes>* U8 TDI Data for TDI. NumBytes calculates as follows: NumBytes = (NumBits + 7) >> 3
Direction Data Name Explanation
H<-E <NumBytes>* U8 TDO TDO data. NumBytes calculates as follows: NumBytes = (NumBits + 7) >> 3
H<-E 1 * U8 Return Return value: 0: O.K. Everything else: Error occured.
Response
Additional information
How the JTAG sequence is generated is beyond the scope of this manual.
This command is available for J-Links with hardware version 5 and above only.
The hardware version can be retrieved using the command
EMU_CMD_GET_HW_VERSION on page 32.
Sample communication
Output Command and JTAG TDI, TMS data to halt ARM7 CPU.
H->E: CF 00 48 00 86 E3 71 C0 01 00 00 00 0C 20 00 18 02 00 00 00 00 00
Returns TDO data.
H<-E: 20 00 08 00 48 00 00 00 00
Returns O.K.
H<-E: 00
下面做了一些简单的封装,以及在逻辑分析仪上的抓图:
1. 复位JTAG逻辑
CODE:
int testLogicReset(void) { int i = 0; jlink_tap_init();
for (i = 0; i < 8; i++) { jlink_tap_append_step(1, 0); } jlink_tap_execute(); jlink_tap_init(); } |
WAVE:
URL:http://hi.csdn.net/attachment/201002/9/3466916_1265731414dFif.jpg
2. 扫描JTAG链:
CODE:
unsigned int dcScan(void) { unsigned int idcode = 0xffffffff; testLogicReset(); sendData(INT_ID_CODE_LEN, (char *)&idcode, false); idcode = buf_get_u32(tdo_buffer,8,32); return idcode; } |
WAVE:
注释:testLogicReset()对应的波形在7ms以前,样子和上图一样
URL:
http://hi.csdn.net/attachment/201002/9/3466916_12657353076oWz.jpg
3. BYPASS指令测试:
CODE:
unsigned int doBypass(unsigned val) { unsigned int ret = 0; testLogicReset(); sendInstruction(8, STR_PQ27E_INSTRU_BYPASS); sendData(INT_ID_CODE_LEN, (char *)&val, false); ret = buf_get_u32(tdo_buffer,8,32); } |
WAVE:
sendInstruction(8, STR_PQ27E_INSTRU_BYPASS);
URL:
http://hi.csdn.net/attachment/201002/9/3466916_12657317989YCr.jpg
sendData(INT_ID_CODE_LEN, (char *)&val, false);
URL:
http://hi.csdn.net/attachment/201002/9/3466916_1265731915j78v.jpg