【米尔瑞萨RZ/G2L开发板-创新应用】 Red Magic PRO4RZ
Red Magic PRO4RZ经过这段时间的加紧补作业,最终实现了在 PC 端通过 RZ/G2 使用 arm-none-eabi-gdb 完成对 stm32f103 控制器的探测和调试。项目的硬件结构框图如下:硬件主要分为三个模块,GZ/G2 作为核心,对上和 PC 通信,完成 gdb 协议的解析和转译;对下通过虚拟的 SWDIO 接口(软件实现的)和待调试的板子通信,实现待调试芯片的底层数据交互。
而本次项目设计到软件部分涉及到两个层次,分别是内核态和用户态,内核太涉及到 USB gadget 驱动的开发,实现了设备端点在PC端枚举成 tty 设备,用户态涉及到 blackmagic 的移植,官方这部分功能是运行在 stm32 这类处理器上的,我将这部分功能移植到了 Linux 的用户态。系统软件结构框图如下:
整个软件的开发都采用 git 进行代码托管,内核态的开发仓库为 https://github.com/iysheng/myir-renesas-linux,代码提交记录截图如下:
用户态的代码开发在仓库 https://github.com/iysheng/blackmagic, 对应的提交记录截图如下:
因为前面大部分时间都在围绕 USB gadget 进行,所以用户态代码这部分的开发显示非常急促,还好我之前有对 blackmagic 这个项目的代码有过一定的拜读,所以基本功能还是实现了,目前可以探测外接芯片的信息,测试可以擦除 stm32f1 的内部 flash。
有关 blackmagic 这个调试器,我自己还是 DIY 过一个实际的调试器的,硬件我也已经开源了 https://gitee.com/iysheng/RedMagicProbe
实物是这个样子的:
现场使用 RZ/G2 实现 blackmagic probe 的工具还是有一定的挑战的,测试的现场图片如下:
从图中可以看出 RZ/G2 通过 4 根线和待调试的 STM32 的一个板子链接起来,相关的接口在原理图中我标注出来了如下所示:
在 J20 这个插座中,使用了 1 号脚 作为 3V3 给板子供电,39 作为连接板子的 GND,11 作为 SWCLK, 13 作为 SWDIO。有关 SWD 管脚部分的初始化参看代码:
int gpio_handler_init(void)
{
struct gpiohandle_data data;
char chrdev_name;
int fd, ret;
strcpy(chrdev_name, "/dev/gpiochip0");
/*Open device: gpiochip0 for GPIO bank A */
fd = open(chrdev_name, 0);
if (fd == -1) {
ret = -errno;
fprintf(stderr, "Failed to open %s\n", chrdev_name);
return ret;
}
swdp_pins.lineoffsets = 33;
swdp_pins.flags = GPIOHANDLE_REQUEST_OUTPUT;
swdp_pins.lines = 1;
memcpy(swdp_pins.default_values, &data, sizeof(swdp_pins.default_values));
strcpy(swdp_pins.consumer_label, "swdio");
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &swdp_pins);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n",
ret);
}
swdp_pins.lineoffsets = 322;
swdp_pins.flags = GPIOHANDLE_REQUEST_OUTPUT;
swdp_pins.lines = 1;
memcpy(swdp_pins.default_values, &data, sizeof(swdp_pins.default_values));
strcpy(swdp_pins.consumer_label, "swclk");
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &swdp_pins);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n",
ret);
}
if (close(fd) == -1)
perror("Failed to close GPIO character device file");
return ret;
}
最终测试的效果如图所示:
具体测试步骤如下:
[*] 在 RZ/G2 端加载对应的驱动,就会枚举出来 /dev/ttyBMP0
[*] 在 RZ/G2 端执行 ./blackmagic APP 开启服务程序(因为我编译出来的是 DEBUG 开启的版本,所以在和 PC 端 gdb 交互的过程中打印出来很多内容,这在初期调试阶段是很有必要)
[*] 在 PC 端执行 arm-none-eabi-gdb 关联 RZ/G2 枚举出来的 /dev/ttyACM0 接口 target extended-remote /dev/ttyACM0, 对应的 RZ/G2 端就会打印出来很多内容
[*] 接着在 PC 端执行 monitor swdp_scan 就可以探测出来连接的 STM32F103 芯片
从最终测试的效果图中可以看出,PC 端已经识别出来了 STM32F1 的芯片。并且在 RZ/G2 端也打印出u来来了芯片的 DPIDR 等信息。通过这个项目,我的收获主要有以下几个方面:
[*]通过阅读内核有关 usb gadget 驱动代码,使我对 USB gadget 的代码框架有一个一点浅薄的了解,这部分可以从我在阅读代码中添加的标注中看到,USB 部分也是我下一个阶段希望学习的方向,借着这个机会对主办方举行的活动表示感谢,如果没有这个活动,我可能还不会这么努力地去看内核 USB 的相关代码(如果缺少项目支撑,相信学习的进度不会这么快)
[*]通过 blackmagic 到 Linux 用户态的移植让我对对底层的 gdb 调试原理以及 SWDP 协议规范有了进一步的了解。因为我作为一个嵌入式软件开发人员,我比较喜欢探求更深层次的代码实现,而不是单单完成一些库的调用,可能是我毕业就从事 Linux BSP 开发有关的缘故吧。我认为如果能够对 ARM Debug Interface 这类规范实现有更深的了解,相信对软件优化以及BUG调试会有很好的帮助。此外,如果研究的更加底层,那么肯定会有助成为一名真正的极客,这也是我作为嵌入式开发人员的个人追求。
页:
[1]