玩zynq板子的,是不是受够了platform usb cable 那乌龟一样的下载速度了?现在好了,使用手上的廉价jlink就可以调试zynq 芯片,速度还飞快。
最近搞zynq开发,实在是无法忍受platform usb cable那个下载调试速度,所以一直在找有没有更好的调试方法,结果发现xilinx官方提供了个XVC虚拟调试电缆这个东西。然后花了点时间研究了一下,发现实现起来还挺简单,所以打算自己搞一个试试,然后突发奇想,能不能省事点,直接用jlink来干这事?灵光一闪,想到了jlink其实有SDK的,可以通过程序自己控制jlink读写芯片,所以觉得这个想法应该是可行的,然后随便bing搜了下,好像没看到有先例,所以这个螃蟹只能我自己先尝尝了。。。
废话就不多说了,直接说关键点就好,感兴趣的可以自己深入研究。首先xilinx提供了xvc的详细文档xapp-1251,里面有xvc的协议说明,还提供了GitHub地址,里面有xvc server的实现代码,由于我使用的是window环境,因此我把xvc server代码下载下来,然后简单修改移植到了window,然后把里面的axi to jtag的操作代码替换为jlink sdk的jtag读写操作函数上,简单搞搞。不到半天就搞定了,
xvc server内主要修改了int handle_data这个函数
int handle_data(int fd)
{
do
{
memset(cmd, 0, 32);
if (sread(fd, cmd, 2) != 1)
return 1;
if (memcmp(cmd, "ge", 2) == 0)
{
if (sread(fd, cmd, 6) != 1)
return 1;
memcpy(TDO, xvcInfo, strlen(xvcInfo));
if (send(fd, (const char*)TDO, strlen(xvcInfo),0) != strlen(xvcInfo))
{
perror("write");
return 1;
}
if (verbose)
{
printf("%u : Received command: 'getinfo'\n", (int)time(NULL));
printf("\t Replied with %s\n", xvcInfo);
}
break;
}
else if (memcmp(cmd, "se", 2) == 0)
{
if (sread(fd, cmd, 9) != 1)
return 1;
memcpy(TDO, cmd + 5, 4);
if (send(fd, (const char*)TDO, 4,0) != 4)
{
perror("write");
return 1;
}
if (verbose)
{
printf("%u : Received command: 'settck'\n", (int)time(NULL));
printf("\t Replied with '%.*s'\n\n", 4, cmd + 5);
}
break;
}
else if (memcmp(cmd, "sh", 2) == 0)
{
if (sread(fd, cmd, 4) != 1)
return 1;
if (verbose)
{
printf("%u : Received command: 'shift'\n", (int)time(NULL));
}
}
else
{
fprintf(stderr, "invalid cmd '%s'\n", cmd);
return 1;
}
int len; //<num bits>
if (sread(fd, &len, 4) != 1)
{
fprintf(stderr, "reading length failed\n");
return 1;
}
int nr_bytes = (len + 7) / 8; //向上取整数字节
if (nr_bytes > sizeof(TDI))
{
fprintf(stderr, "buffer size exceeded\n");
return 1;
}
if (verbose)
{
printf("\tNumber of Bits : %d\n", len);
printf("\tNumber of Bytes : %d \n", nr_bytes);
printf("\n");
}
memset(&TDO, 0, nr_bytes);
if (sread(fd, TMS, nr_bytes ) != 1) //读取tms
{
fprintf(stderr, "reading tms data failed\n");
return 1;
}
if (sread(fd, TDI, nr_bytes) != 1) //读取tdi
{
fprintf(stderr, "reading tdi data failed\n");
return 1;
}
JLINKARM_JTAG_StoreGetRaw((const U8*)&TDI, (U8*)&TDO, (const U8*)&TMS, len);
if (send(fd, (const char*)TDO, nr_bytes,0) != nr_bytes)
{
perror("write");
return 1;
}
break;
} while (1);
return 0;
}
编译好的exe文件,感兴趣的可以试试
https://whycan.com/files/members/7197/XVC.rar
目前有点问题没解决,就是可以下载bit文件但是无法烧写外部flash,目前还搞不清楚原因。
如果需要在vitis内使用xvc,目前我摸索出的方法是在vivado内设置xvc并连接到芯片,然后切换到vitis就可以在debug内找到xvc了,测试vitis内点击debug可以正常下载调试,其他功能未详细测试,目前xvc server速度我设置为30M,对比Platform usb cable真是速度提升明显,吃灰的矿渣zynq板又可以拉出来溜溜了!
由于jlink sdk有版权问题,为避免麻烦,sdk和源码就不上传这里了,sdk在GitHub就可以下载到,自己找找就好
离线
更新一下,下载外部flash是ok的,需要把启动模式设置为JTAG模式即可下载到外部flash
原本使用xilinx usb下载线烧写32M外部flash需要将近15分钟,现在直不到5分钟就搞定了
最近编辑记录 jiaowoxiaolu (2022-04-06 14:15:53)
离线
XilinxVirtualCable能做这么高了? 我之前看别人用ESP或者各种派做的速度都特别低 除了能无线调试 没太大用途
速度瓶颈不在xvc协议,是在具体实现jtag移位出去的硬件上,esp做得大概只实现了功能,没往优化速度上下功夫,我用jlink来实现jtag比特流的输出,一是jlink烂大街,方便获得,0动手成本,2是jlink本身的jtag速度还是挺快的,v8老古董版本的jtag就比官方DLC cable下载器快不少了,土豪用jlink pro或者更高版本的话轻松快到超过zynq jtag最高速度
离线