写在前面
根据我以前的测试,ST-Link V2和Jlink V8在连续读写速度都在160KB/S左右,而大部分CMSIS-DAP调试器受限于全速HID,速度很难提高,
DAPLINK+ OpenOCD的连续读写速度仅有23KB/S。
年初尝试过用NUC505做CMSIS-DAP,505应该是市面上最便宜的集成USB HS PHY单片机,高速HID报文可设置为1024Byte,收发间隔125uS,其USB部分完全没有瓶颈。然而它的SPI模块非常墨迹,在一次传输完成后,还会等待好几个CLK,才会触发完成标志,即使将CLK提升到14MHz,连续读写速度也只有150KB/S的水平,只能说朽木不可雕也。
这次的主角,GD32F350,去年就有所了解,听说是与GD32F150同样的价格,USB部分改成了DWCOTG,后32KB代码执行速度不会蜗牛。详细看完datasheet后,发现内部48M时钟可以通过USB SOF信号校准,这样就不用晶振。价格上号称批量最低30美分,唔,一般般吧,反正我淘宝上买了3pcs,共21元人民币。总的来说,“貌似”超级低廉的方案价格,类似ST-LinkV2主芯片的SPI设计,说不定也可以达到160KB/S的主流速度指标,值得一试。
一、硬件设计
硬件肯定越简单越好,一颗QFN28的GD32F350,再加点电阻电容即可。考虑到bootloader和适配外壳,再加一颗按键和一颗双色led,开发阶段需要引出调试接口,得用LQFP48封装芯片,所以测试板做了二选一兼容。硬件资料见这个
帖子。
二、软件设计
设计要求: 在保留CMSIS-DAP调试器基本功能的同时,尽可能压榨GD32F350的芯片潜力,通过OpenOCD专用驱动配合USB BULK传输方式,最大化的提升SWD/JTAG调试速度。
功能要求:
- 支持SWD+SWO、JTAG调试接口
- 支持一路USBCDC串口
- 兼容CMSIS-DAP HID协议,各平台下免驱使用
- 开发BULK传输接口
- OpenOCD BULK传输接口的支持
- 模拟U盘方式的Bootloader
硬件驱动开发部分关键点:
- GD32F350集成的DWCOTG仅支持4个双向端点,其中0号控制端点、1号用于BULK传输接口、2号用于CMSIS-DAP HID接口、3号用于CDC数据接口、4号被配置成CDC控制接口,但4号端口实际并不存在,设备永远返回NAK应答,这并不会影响CDC串口功能。
- CDC串口支持上位机配置波特率,范围为:8M、4M、3.2M-2K。高速串口驱动的设计细节见这个帖子。
- SWD接口部分,将一路SPI中的CLK用于输出SWCLK,将MISO与MOSI合并用于实现SWDIO,以具体波形为例:
如图,SWD传输基本单元的波形时序由三大块组成:请求、应答和数据,各块之间还有些空闲BIT。其中请求8bit,应答块及其前后空闲bit不确定,数据块包含32bit数据及其尾部空闲BIT。各块之间的传输方向可能不一致,所以需要分成三段处理,在GD32F350中,16bit的连续波形通过SPI 16bit模式完成传输(如上图中的数据块),8bit的连续波形通过SPI 8bit模式完成传输(如上图中的请求块),剩余波形通过IO翻转完成(如上图中的应答块)。DAPLINK中所有硬件都用GPIO翻转完成时序操作,本人在实际优化过程中,GPIO最快频率可达8M,但此模式会占用大量CPU,感觉不是很妥当。
- JTAG接口部分,类似SWD接口,一路主SPI,一路从SPI,以具体波形为例:
思路上也是满8字节既通过SPI收发,剩余字节则GPIO翻转,JTAG部分还未进行过时序优化,所以并没有16BIT连续波形,GPIO翻转延迟也偏大。
协议开发:
在之前NUC505方案中就完成了协议层代码,逻辑上与CMSIS-DAP相同,但将协议层与驱动层解耦,协议层可以异步调用传输接口,然后等待传输完成事件,NUC505的驱动部分也是完全非阻塞的。这种设计思路听起来很美好,非阻塞不是美好的代名词吗?然而现实就喜欢打脸,驱动层的非阻塞必然引入中断机制的时钟开销,异步事件必然引入程序调度开销,最终结果就是CPU内核不忙活,SWD时序波形却一大堆空白,很不好看。这次使用GD32F350开发时,也遇到这个问题,最终的解决方法就是让整个协议层和SWD/JTAG驱动层耦合,并且在main中运行,而其他程序统统运行于pendsv或更高优先级的驱动中。
三、功能测试
已通过的测试:
- Openocd 0.10 CMSIS-DAP模式 SWD接口测试,速率范围1M-32M
- Openocd 0.10 CMSIS-DAP模式 JTAG接口测试,速率范围1M-8M
- Openocd 0.10 BULK模式 SWD接口测试,速率范围1M-32M
- Openocd 0.10 BULK模式 JTAG接口测试,速率范围1M-8M
- IAR 7.80.3 CMSIS-DAP模式 SWD接口测试,速率范围1M-32M/AUTO
- IAR 7.80.3 CMSIS-DAP模式 JTAG接口测试,速率范围1M-8M/AUTO
- USBCDC功能,已测试的最大波特率为921600
未完成的测试:
- SWO功能,貌似IAR不支持CMSIS-DAP的SWO功能,此问题未深究
OpenOCD CMSIS-DAP模式SWD传输速度:
懒得提,23KB/S。
OpenOCD BULK模式SWD传输速度:
操作 | 传输速度 |
4MHz读 | 102KB/S |
4MHz写 | 106KB/S |
8MHz读 | 123KB/S |
8MHz写 | 132KB/S |
16MHz读 | 128KB/S |
16MHz写 | 150KB/S |
32MHz读 | 142KB/S |
32MHz写 | 156KB/S |
BULK模式比免驱HID厉害很多,但为啥速度还比不上ST-LINK V2/JLINK V8呢,继续看波形:
4MHz写操作局部波形
8MHz写操作局部波形
16MHz写操作局部波形
32MHz写操作局部波形
很明显,问题还在USB传输上,这锅得由OpenOCD驱动来背,CMSIS-DAP协议支持命令的队列操作,然而驱动开发者仅使用了一发一收的方式进行[
源码],我虽然换了BULK驱动,但只是Ctrl+C,Ctrl+V常规操作[
源码],所以USB数传上依然是一发一收,整个上下位机构成一个大大的阻塞操作环,不慢才怪。所以后面还得重构一份OpenOCD驱动,使用异步队列方式发送命令,这个修改需要开发者对OpenOCD整体有一定的熟悉,所以这几天是不想搞了。
然后,得展望下未来,使用异步队列方式,或者说将上面四幅波形图的空白处都填满波形后,SWD速度能达到多少呢?4MHz可以接近200K、8MHz则在300KB左右、16MHz在400KB左右、32Mhz也许能超500KB。哈哈,真香。届时,我就发个帖子《0.3美金,买不了吃亏买不了上当,拳打ST,脚踩J-Link,不是FPGA,就都给我趴下》
最后,JTAG速率很烂,就不说了。
四、制作及测试用例
由于上位机驱动并不完美,所以未尝试构建Windows系统下的可执行程序,有兴趣的Linux用户请自行编译把。
五、后续
先搞定异步队列驱动,再弄个Bootloader,优化下JTAG波形,CDC串口也要支持模式配置,SWD驱动中的部分代码也有优化空间。
-------------------------------------------------
2018年11月5日更新:
支持USB Bulk异步乒乓传输;CDC串口支持模式配置;略微优化SWD;完成SWD稳定性测试;SWD @16M 速度可达400KB/S。
下载附件后,git pull拉取最新版本,或者直接访问:
https://github.com/vllogic/vllink_lite
本帖最后由 le062 于 2018-11-5 05:52 编辑