P1.L = LO(DBGSTAT);
P1.H = HI(DBGSTAT);
R1.L = 0x0002;
R1.H = 0x0000;
.loop_dbgstat:
R0 = [P1];
R0 = R0 & R1;
cc = R0 == R1;
if cc jump .write_emudat;
jump .loop_dbgstat;
.write_emudat:
R0 = EMUDAT;
[P0++] = R0;
jump .loop_dbgstat;
void
part_emudat_set_new (chain_t *chain, int n, uint32_t value, int exit)
{
part_t *part;
tap_register *r;assert (exit == EXITMODE_UPDATE || exit == EXITMODE_IDLE);
if (part_scan_select (chain, n, EMUDAT_SCAN) < 0)
return;part = chain->parts->parts[n];
r = part->active_instruction->data_register->in;
emudat_init_value (r, value);
chain_shift_data_registers_mode (chain, 0, 1, exit);
}
static char default_jtag_connect[] = "cable gnICE";
修改为
static char default_jtag_connect[] = "cable USB-to-JTAG-IF ftd2xx-mpsse 0725:6010";
static char default_jtag_frequency[] = "frequency 6000000";
static void
core_emudat_set_new (int core, uint32_t value, int runtest)
{
part_emudat_set_new (cpu->chain, core, value,
runtest ? EXITMODE_IDLE : EXITMODE_UPDATE);
}
static void
cache_flush (int core, uint32_t addr, int size)
{
uint32_t p0;
int i;assert (size > 0);
if (size <= 4)
{
p0 = core_register_get (core, REG_P0);core_register_set (core, REG_P0, addr);
core_dbgctl_bit_set_emuirlpsz_2 (core, UPDATE);
for (i = (size + addr % CACHE_LINE_BYTES - 1) / CACHE_LINE_BYTES + 1;
i > 0; i--)
core_emuir_set_2 (core, gen_flush (REG_P0),
gen_iflush_pm (REG_P0), RUNTEST);
core_dbgctl_bit_clear_emuirlpsz_2 (core, UPDATE);core_register_set (core, REG_P0, p0);
}
static int
memory_write (int core, uint32_t addr, uint8_t *buf, int size)
{
uint32_t p0, r0, p1, r1, pc;
int clobbered[BFIN_DCPLB_NUM];
int i;
uint8_t isram_backup[32];assert (size > 0);
p0 = core_register_get (core, REG_P0); //保护各个寄存器
p1 = core_register_get (core, REG_P1);
r0 = core_register_get (core, REG_R0);
r1 = core_register_get (core, REG_R1);
pc = core_register_get (core, REG_RETE);for (i = 0; i < BFIN_DCPLB_NUM; i++)
clobbered = 0;dcplb_validate_clobber_p0r0 (core, addr, size, clobbered);
core_register_set (core, REG_P0, addr);
core_dbgctl_bit_set_emuirlpsz_2 (core, UPDATE);
if ((addr & 0x3) != 0)
core_emuir_set_2 (core,
gen_move (REG_R0, REG_EMUDAT),
gen_store8pi (REG_P0, REG_R0), UPDATE);while ((addr & 0x3) != 0 && size != 0)
{
core_emudat_set (core, *buf++, RUNTEST);
addr++;
size--;
}
if (size == 0)
goto finish_write;if (size >= 4)
{
bfin_resume_from_addr(0, 0, 0xffa08000); //启动已经储存在0xffa08000的CPU DCC扫描程序for (; size >= 4; size -= 4)
{
uint32_t data;
data = *buf++;
data |= (*buf++) << 8;
data |= (*buf++) << 16;
data |= (*buf++) << 24;
core_emudat_set_new (core, data, RUNTEST); //往共享寄存器里写数据
}
bfin_stop(); //停止CPU DCC扫描程序
}if (size == 0)
goto finish_write;core_emuir_set_2 (core,
gen_move (REG_R0, REG_EMUDAT),
gen_store8pi (REG_P0, REG_R0), UPDATE);for (; size > 0; size--)
core_emudat_set (core, *buf++, RUNTEST);finish_write:
core_dbgctl_bit_clear_emuirlpsz_2 (core, UPDATE);
dcplb_restore_clobber_p0r0 (core, clobbered);
core_register_set (core, REG_P0, p0); //恢复各个寄存器
core_register_set (core, REG_P1, p1);
core_register_set (core, REG_R0, r0);
core_register_set (core, REG_R1, r1);
core_register_set (core, REG_RETE, pc);return 0;
}
char *freq_string = default_jtag_frequency;
{"freq", required_argument, 0, 18},
case 18:
strcpy(freq_string, "frequency ");
strcat(freq_string, optarg);
break;
jtag_parse_line (chain, freq_string);
uint32_t dcc_code[] =
{
0x5008e109,
0xffe0e149,
0x0002e101,
0x0000e141,
0x54089108,
0x18020808,
0x31c72ffc,
0x2ff99200,
}; //CPU DCC扫描程序机器码
bfin_write_mem(0xffa08000, (uint8_t *) dcc_code, 0x20);
还有一个值得说的是,http://blackfin.uclinux.org上最新的urjtag源码中使用了strcasestr函数,这个函数在cygwin的gcc的glibc里面没有,编译无法通过。不过没有关系,可以自己写一个。
#include <ctype.h>
#ifndef HAVE_STRCASESTR
char * strcasestr (char *haystack, char *needle)
{
char *p, *startn = 0, *np = 0;for (p = haystack; *p; p++) {
if (np) {
if (toupper(*p) == toupper(*np)) {
if (!*++np)
return startn;
} else
np = 0;
} else if (toupper(*p) == toupper(*needle)) {
np = needle + 1;
startn = p;
}
}return 0;
}
#endif
今天就写到这里。过一段时间我会放出整理测试后的源代码以及可执行文件,如果你觉得修改过程太过复杂,可以直接使用我写的代码。
这篇文章主要是讲如何编译MumJTAG的ARM和Blackfin GDB调试代理程序的,如果你对GDB调试还没有什么概念,可以看这篇文章:http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!268.entry。如果你想知道怎么使用OpenOCD进行ARM调试,请看这篇文章:http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!485.entry。如果你想知道ARM上GDB调试怎么和Eclipse接口,请看这篇文章:http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!602.entry。
MumJTAG是我设计的一个JTAG调试电缆,它的制作请看这篇文章:http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!786.entry。
本文在Windows下用Cygwin环境,配合FT2232的D2XX驱动,成功编译了OpenOCD、urjtag和gdbproxy;换句话说,采用本文介绍的方法,可以在Windows下使用FTDI提供的驱动,使用FT2232电缆。OpenOCD在Cygwin下的编译没有什么难度,urjtag和gdbproxy的编译,因为没有找到类似的文章,我花了2天的时间……希望我的记录能给大家提供些方便,不要走我的弯路。转载请注明来自我是一只鱼同学的EE小站,邮件cosine@126.com。
另外说一下,其实ADI提供了Windows环境下的gdbproxy,但是我试了下,不好使,也许是因为它用的是libftdi驱动的原因,我没有调查在Windows环境下怎么装libftdi驱动,因为我想绝大多数人会使用D2XX驱动吧。给出ADI工具链的地址:http://blackfin.uclinux.org/gf/download/frsrelease/392/5211/blackfin-toolchain-win32-2008R1.5.exe。
这个很简单,大家可以看OpenOCD的手册:http://openocd.berlios.de/doc/openocd.pdf。我这里再啰嗦一遍。
先到OpenOCD的官方网站:http://openocd.berlios.de/,下载OpenOCD源代码:http://prdownload.berlios.de/openocd/openocd-0.1.0.tar.gz,假设保存为E:\Mum\OpenOCD\openocd-0.1.0.tar.gz。用命令行来说明:
$ cd /cygdrive/e/mum
$ tar xvzf openocd-0.1.0.tar.gz
$ mv openocd-0.1.0 openocd当然也可以用svn下载OpenOCD最新的版本,在Cygwin的命令行中输入:
$ cd /cygdrive/e/mum
$ svn checkout svn://svn.berlios.de/openocd/trunk openocd
$ cd openocd
$ ./bootstrap然后准备MumJTAG的D2XX驱动程序,可以看之前的这篇文章制作一个:http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!786.entry,或者到这里下载我做好的驱动:http://cid-4201fdc93932ddaf.skydrive.live.com/self.aspx/Mum%e8%ae%a1%e5%88%92/MumJTAG/MumJTAGDriver.rar,假设驱动程序存储在E:\Mum\MumJTAGDriver。现在可以编译了,还是用命令来说明。
$ cd /cygdrive/e/mum/openocd
$ ./configure --prefix=/cygdrive/e/mum/openocd/build --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=/cygdrive/e/mum/mumjtagdriver
$ make
$ make install这样,OpenOCD就编译好,并拷贝到E:\Mum\OpenOCD\build里了。
为了让OpenOCD正常工作,还需要一个针对要调试的CPU的配置文件,这个配置文件的编写可以参考OpenOCD的手册。这里我给出我编写的MumJTAG连接AT91SAM9263的配置文件:
##########################
# Interface configuration
##########################interface ft2232
ft2232_device_desc "MumJTAG A"
ft2232_layout "usbjtag"
ft2232_vid_pid 0x0725 0x6010
jtag_khz 8
reset_config trst_and_srst##########################
# TAP configuration
##########################jtag newtap at91sam9263 cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x0792603F
jtag_nsrst_delay 200000
jtag_ntrst_delay 200000##########################
# Target configuration
##########################set _TARGETNAME [format "%s.cpu" at91sam9263]
target create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME -variant arm926ejs# Internal sram1 memory
$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x00300000 -work-area-size 0x1000 -work-area-backup 1##########################
# Port configuration
##########################telnet_port 23
gdb_port 2331
tcl_port 6666值得一提的是,不同JTAG电缆的ft2232_device_desc、ft2232_vid_pid是不一样的,应根据实际修改;ft2232_layout设定的是电缆的类型,OpenOCD支持很多种电缆的类型,MumJTAG兼容USB to JTAG Interface,所以写“usbjtag”;如果你自己独创了一种电缆,就要修改OpenOCD的源代码。假设将配置文件保存为E:\Mum\OpenOCD\build\AT91SAM9263.cfg,接下来连接MumJTAG到目标板的JTAG,给目标板上电就可以启动OpenOCD了,如下所示。
$ cd /cygdrive/e/mum/openocd/build/bin
$ ./openocd -f /cygdrive/e/mum/openocd/build/mumjtag.cfg
Open On-Chip Debugger 0.1.0 (2009-04-15-16:59) Release
BUGS? Read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS
$URL: https://kc8apf@svn.berlios.de/svnroot/repos/openocd/tags/openocd-0.1.0/src
/openocd.c $
8 kHz
Info : JTAG tap: at91sam9263.cpu tap/device found: 0x0792603f (Manufacturer: 0x0
1f, Part: 0x7926, Version: 0x0)
Info : JTAG Tap/device matchedOpenOCD自带很多CPU和JTAG电缆的配置文件,在安装目录里,它的使用就不细说了,大家自己看手册。
urjtag和gdbproxy是uclinux下的一个项目,由ADI官方派人维护。它是可以使用FT2232电缆通过JTAG调试Blackfin系列处理器的一套GDB调试服务程序。顺便提一下,FT2232电缆无法在ADI的Visual DSP++下使用。
urjtag和gdbproxy是一体的一套软件,他们必须一同编译,而且路径有要求,例如urjtag储存在E:\Mum\urjtag_gdbproxy\jtag,那么gdbproxy就必须储存在E:\Mum\urjtag_gdbproxy\gdbproxy。编译的顺序是先urjtag后gdbproxy。urjtag和gdbproxy的编译和使用可以参考blackfin.uclinux.org的wiki,地址是:http://docs.blackfin.uclinux.org/doku.php?id=toolchain:debug:gdbproxy。
先到uclinux的官方网站下载urjtag和gdbproxy的源码,地址是:http://blackfin.uclinux.org/gf/download/frsrelease/392/5076/blackfin-jtag-tools-08r1.5-14.src.tar.bz2。将其中的jtag.tar.bz2、gdbproxy.tar.bz2和jtag.diff解压出来,例如储存为E:\Mum\urjtag_gdbproxy\jtag.tar.bz2、E:\Mum\urjtag_gdbproxy\gdbproxy.tar.bz2和E:\Mum\urjtag_gdbproxy\jtag.diff。然后:
$ cd /cygdrive/e/mum/urjtag_gdbproxy
$ tar xvjf jtag.tar.bz2
$ tar xvjf gdbproxy.tar.bz2
$ patch -p0 <jtag.diff当然可以使用svn下载最新的代码:
$ cd /cygdrive/e/mum/urjtag_gdbproxy
$ svn checkout svn://sources.blackfin.uclinux.org/toolchain/trunk/jtag jtag
$ svn checkout svn://sources.blackfin.uclinux.org/toolchain/trunk/gdbproxy gdbproxy假设MumJTAG的驱动程序存放E:\Mum\MumJTAGDriver,可以编译urjtag:
$ ./configure --prefix=/cygdrive/e/mum/newbuild/jtag/build --with-ftd2xx=/cygdrive/e/mum/mumjtagdriver
$ make
$ make install我编译的时候有很多参数类型不匹配的警告,无视它们了……接下来编译gdbproxy,这个优点麻烦,首先确认在你的Cygwin里安装的GCC必须是4.X版本的,然后编辑E:\Mum\urjtag_gdbproxy\gdbproxy\configure.in,找到这段
if test "$host_os" = "cygwin" ; then
CFLAGS="$CFLAGS -mno-cygwin"
LIBS="$LIBS -lws2_32"
fi改成这样
if test "$host_os" = "cygwin" ; then
# CFLAGS="$CFLAGS -mno-cygwin"
LIBS="$LIBS -lws2_32 -lintl -lioperm /cygdrive/e/Mum/MumJTAGDriver/i386/ftd2xx.lib"
fi解释下,应该是gdbproxy的Makefile兼容性不够好,用Cygwin 3.X的GCC有很多错误。另外用4.X的GCC也必须加上intl、ioperm等库,我不太懂Makefile的编写,希望明白的大虾们予以指正。另外,必须加上FTD2XX库,这个库就在驱动程序的目录里,例如前文的E:\Mum\MumJTAGDriver\i386\ftd2xx.lib。然后就可以编译了:
$ cd /cygdrive/e/mum/urjtag_gdbproxy/gdbproxy
$ CC="gcc-4" ./configure --prefix=/cygdrive/e/mum/urjtag_gdbproxy/gdbproxy/build
$ make
$ make installgdbproxy没有什么配置文件,但是需要在初始化的时候指定JTAG电缆的种类。使用的时候先将MumJTAG连上目标板并给目标板上电,然后:
$ cd /cygdrive/e/mum/urjtag_gdbproxy/gdbproxy/build/bin
$ ./gdbproxy bfin --connect="cable USB-to-JTAG-IF ftd2xx-mpsse 0725:6010"Remote proxy for GDB, v0.7.2, Copyright (C) 1999 Quality Quorum Inc.
MSP430 adaption Copyright (C) 2002 Chris Liechti and Steve Underwood
Blackfin adaption Copyright (C) 2008 Analog Devices, Inc.GDBproxy comes with ABSOLUTELY NO WARRANTY; for details
use `--warranty' option. This is Open Source software. You are
welcome to redistribute it under certain conditions. Use the
'--copying' option for details.Initializing on FTDI device 0725:6010
IR length: 5
Chain length: 1
Device Id: 01000010011110100101000011001011 (0x00000000427A50CB)
Manufacturer: Analog Devices
Part(0): BF533
Stepping: 4
Filename: /cygdrive/e/mum/urjtag_gdbproxy/jtag/build/share/urjtag/analog/b
f533/bf533
warning: bfin: no board selected, BF533 is detected
notice: gdbproxy: waiting on TCP port 2000这说明gdbproxy已经找到目标CPU了。gdbproxy也支持很多种FT2232电缆,MumJTAG兼容USB to JTAG Interface,所以写“USB-to-JTAG-IF”;我用的是FTD2XX的驱动,所以写“ftd2xx-mpsse”,“0725:6010”是VID和PID。具体的使用说明,请看blackfin.uclinux.org的wiki。
如果你觉得以上这一切都很麻烦,那么,你可以从EE小站的SkyDrive下载已经编译好的OpenOCD、urjtag和gdbproxy。注意,这些程序必须使用FTDI官方的FTD2XX驱动;这些程序只能在Windows下运行。我测了下,应该不需要Cygwin的Dll;如果不是这样,请留言,我会把Dll加上。地址如下:
OpenOCD:http://cid-4201fdc93932ddaf.skydrive.live.com/self.aspx/Mum%e8%ae%a1%e5%88%92/MumJTAG/OpenOCD.rar
urjtag_gdbproxy:http://cid-4201fdc93932ddaf.skydrive.live.com/self.aspx/Mum%e8%ae%a1%e5%88%92/MumJTAG/urjtag%7C_gdbproxy.rar
...[FtdiHw]
%USB\VID_0403&PID_6001.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_6001
%USB\VID_0403&PID_6010&MI_00.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_6010&MI_00
%USB\VID_0403&PID_6010&MI_01.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_6010&MI_01
%USB\VID_0725&PID_6010&MI_00.DeviceDesc%=FtdiBus.NT,USB\VID_0725&PID_6010&MI_00
%USB\VID_0725&PID_6010&MI_01.DeviceDesc%=FtdiBus.NT,USB\VID_0725&PID_6010&MI_01[FtdiHw.NTamd64]
%USB\VID_0403&PID_6001.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_6001
%USB\VID_0403&PID_6010&MI_00.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_6010&MI_00
%USB\VID_0403&PID_6010&MI_01.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_6010&MI_01
%USB\VID_0725&PID_6010&MI_00.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0725&PID_6010&MI_00
%USB\VID_0725&PID_6010&MI_01.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0725&PID_6010&MI_01...[Strings]
Ftdi="FTDI"
DESC="CDM Driver Package"
DriversDisk="FTDI USB Drivers Disk"
USB\VID_0403&PID_6001.DeviceDesc="USB Serial Converter"
USB\VID_0403&PID_6010&MI_00.DeviceDesc="USB Serial Converter A"
USB\VID_0403&PID_6010&MI_01.DeviceDesc="USB Serial Converter B"
USB\VID_0725&PID_6010&MI_00.DeviceDesc="JTAG Port"
USB\VID_0725&PID_6010&MI_01.DeviceDesc="USB Serial Converter"
SvcDesc="USB Serial Converter Driver"
ClassName="USB"
...[FtdiHw]
%VID_0403&PID_6001.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_6001
%VID_0403&PID_6010.DeviceDesc%=FtdiPort2232.NT,FTDIBUS\COMPORT&VID_0403&PID_6010
%VID_0725&PID_6010.DeviceDesc%=FtdiPort2232.NT,FTDIBUS\COMPORT&VID_0725&PID_6010[FtdiHw.NTamd64]
%VID_0403&PID_6001.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6001
%VID_0403&PID_6010.DeviceDesc%=FtdiPort2232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6010
%VID_0725&PID_6010.DeviceDesc%=FtdiPort2232.NTamd64,FTDIBUS\COMPORT&VID_0725&PID_6010...[Strings]
FTDI="FTDI"
DESC="CDM Driver Package"
DriversDisk="FTDI USB Drivers Disk"
PortsClassName = "Ports (COM & LPT)"
VID_0403&PID_6001.DeviceDesc="USB Serial Port"
VID_0403&PID_6010.DeviceDesc="USB Serial Port"
VID_0725&PID_6010.DeviceDesc="MumJTAG"
SvcDesc="USB Serial Port Driver"
SerEnum.SvcDesc="Serenum Filter Driver"
文章评论(0条评论)
登录后参与讨论