您尚未登录。

楼主 #1 2020-02-27 13:33:32

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

最近一段时间在鼓捣CMSIS-DAP在CH558的移植。现在终于搞定SWD部分了,分享一下结果。
对于CMSIS-DAP,ARM官方的代码是针对32位环境优化的,对于51这种8位单片机就会导致效率很低。因此,我重写了CMSIS-DAP代码(核心部分的代码基本都是汇编写的),将其移植到CH558上,并且使用SPI进行优化(同时依然可以使用GPIO模拟引脚)。
下图是我在STM32F407上的测试结果,使用IAR下载程序(顺便一提,为了提升下载速度,我将Flash的并行编程宽度改成了32位)。
TinyDAP-Flash.png
上图是Flash的测试结果,下载速度70KB/s,验证速度315KB/s。
TinyDAP-SRAM.png
上图是SRAM的测试结果,下载速度305KB/s。

可以看到,即使是CH558这种级别的单片机也可以跑到很高的速度,完全可以满足使用要求。实际上,我的代码大小仅为3.69KB,继续添加功能的空间还是充足的,目测把CMSIS-DAP的所有功能都做上去不成问题,甚至可以考虑做个兼容V1和V2的版本(使用Vendor Command切换版本,兼容一些不支持V2的软件)。
下一步我打算将代码移植到CH552上,毕竟CH552的性价比更高,而且需要修改的部分很少。虽然CH552的时钟频率较低(3.3V下只能跑到16MHz),但是应该对性能的影响不是特别严重(SWD接口带宽还有一定余量),值得尝试。
考虑到JTAG部分以及一些相对次要重要的功能(例如SWO和充话费送的串口)还没完成,所以暂时不放出源代码,待修改完成后再发布,敬请期待。

下文会谈一些目前的优化手段,欢迎大家交流。

最近编辑记录 metro (2020-02-27 13:34:09)

离线

楼主 #3 2020-02-27 16:48:15

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

sblpp 说:

顶起~,感谢楼主分享!
楼主也可以考虑下使用NUC505来搞一个试试
高速USB,价格也很便宜。

其实之前求高速USB就是在考虑做调试器,以后可以试试。

离线

楼主 #4 2020-02-27 16:51:04

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

上述测试结果是基于SPI优化的。这里同样给出GPIO模拟的结果,虽然速度有所损失,但是得益于51单片机操作GPIO的速度(差不多是7个周期对应一个bit),影响并不是特别大。
TinyDAP-GPIO-Flash.png
TinyDAP-GPIO-SRAM.png

离线

楼主 #5 2020-02-27 17:26:28

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

下图是SRAM下载过程中使用逻辑分析仪抓的波形图,是基于GPIO模拟的结果。可以看到,SWD的带宽尚未跑满(大概用了3/4左右),因此乐观估计移植到CH552上的速度损失可以接受(前提是使用SPI跑到8MHz,此时和CH558使用GPIO模拟的理论速度相当)。
TinyDAP-Timing.png

离线

楼主 #7 2020-02-27 17:49:41

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

下面简单介绍一下CMSIS-DAP的特点。
CMSIS-DAP是ARM提的一套调试器协议(作为具体实现之一的DAPLink可能知名度更高?)。CMSIS-DAP的特点是融合了通用调试器(如基于FTDI的方案)和专用调试器(如ST-Link)的优势,即可单独控制输入输出波形,又对Cortex-M的高频操作封装成了固定指令。因此,CMSIS-DAP不仅通用性非常好(理论上可以兼容所有JTAG接口,当然还有自家的SWD接口),而且针对ARM设备可以达到不错的速度(前提是使用V2版本)。
CMSIS-DAP Overview
上图是基于CMSIS-DAP的调试架构。CMSIS-DAP本质上是一套基于PC发送命令并进行处理的中间人,本身并没有决定何时执行哪些命令的功能,这可以简化调试器软件的设计。当然,需要集成相关功能的话也没有问题,例如DAPLink也是利用了这套框架搭了一个基于USB MSC的下载器。
另外,CMSIS-DAP的固件版本包括V1和V2,两者的主要区别在于V1用的是HID,而V2改成了Bulk传输。HID的好处是免驱,但由于HID类的限制每1ms只能传输一条指令,实际上大大限制了传输速度。V2版本则利用WinUSB实现了免驱(对Windows的版本有要求),传输速度也不再受到HID类的限制。(这里要感谢@le062分享的经验,说明了V2版本中USB速度不再是瓶颈,全速USB也是够用的,因此才有了这个想法。)
对V2版本USB部分的详细描述可以查看Configure USB Peripheral

最近编辑记录 metro (2020-02-27 18:01:38)

离线

楼主 #9 2020-02-27 17:59:56

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

上文提到了,CMSIS-DAP是基于命令式的处理,调试器从PC接收指令(Command/Request),在处理结束后调试器整理好结果(Response)发送回PC。由于没有Outstanding(但是可以有内部缓冲),因此指令是顺序执行的,类似于FIFO的架构。因此,CMSIS-DAP的固件内部是一个大的循环,PC端发送的数据会先置于一个FIFO中,待DAP_Thread函数读取、处理指令后,将会写回到另一个FIFO中,等待发送回PC。因此,Command/Request和Response各有一个FIFO,DAP_Thread只处理CMSIS-DAP协议本身,USB部分需要另行处理。
此时看CMSIS-DAP的代码结构(见CMSIS-DAP),就会非常清晰:

  • DAP.c就是DAP的核心部分,用于对指令进行解析和处理。

  • SW_DP.c和JTAG_DP.c用于兼容不同协议的DP(Debug Port)。

  • SWO.c用于SWO的部分。

  • DAP_vendor.c是自定义的DAP指令,可以根据需求添加。

在官方实现中,如果要移植CMSIS-DAP,只需要添加兼容CMSIS-Driver接口的驱动,并且在target或board级进行一些设定(例如I/O端口,特定的重置序列等)就可以用了,还是很方便的。

离线

楼主 #10 2020-02-27 18:03:24

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

ljbfly 说:

厉害,汇编玩的溜!我画了ch563的板子,有高速usb,芯片还没回来,楼主要不要试试,调好硬件送你一块

不敢当不敢当,说实话我想尝试一下NUC505运行调试器的情况,到时候也会试一下的。

离线

楼主 #12 2020-02-27 18:57:51

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

ljbfly 说:

Flash的并行编程宽度,咋设置

Flash-Parallelism.png
IAR的在这里,Keil的我没看。具体可以设置的位数和电压有关,最好参考一下Reference Manual,STM32F407在3.3V下最多可以设为32位。

最近编辑记录 metro (2020-02-27 19:00:07)

离线

楼主 #14 2020-02-27 19:05:20

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

sblpp 说:

刚想起来上次找最便宜的高速USB的MCU的原来是您啊,我也是看了您的那个帖子才做了个505尝试了下
然后就掉坑里了~~~
顺手记录了下505的调试过程。
https://kmcu.gitee.io/2020/02/21/NUC505/

哈哈哈,这个MCU据说坑比较多,之前我也买了块板子打算玩的,结果压箱底了,现在也暂时回不去,打算以后研究下UAC之类的。

离线

楼主 #15 2020-02-27 19:22:15

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

接下来说说优化思路。
首先还是得从CH558的架构说起(CH552等基本同理)。由于51的RAM有限(最大256Bytes),所以USB只能从XRAM读写数据,而众所周知51对XRAM的访问比较麻烦,只能通过DPTR寄存器进行,因此虽然访问速度很快(movx相关的指令都是单周期),但是寻址很麻烦。另外,涉及到数据搬移的部分也会消耗一定时间。
CH558.png
为了解决这个问题,CH55x系列单片机都支持双DPTR指针和自增指针。但是很遗憾,包括Keil(准确说是C51)和SDCC在内的编译器似乎都不支持CH55x上的这两个特性。因此,这部分代码需要按照实际执行的逻辑自己编写代码,这也是要用汇编进行优化的原因之一(另外的原因是可以在固定寄存器上传递跨函数的参数,类似于U-boot的gd指针)。
因此,结合CMSIS-DAP的特点,在我的代码里面,使用DPTR0存储Command指针,DPTR1存储Response指针。由于CH55x支持0xA5指令,这一指令等效于__asm__ ("movx a, @dptr1\ninc dptr1"),因此我们默认使用DPTR0指针。这样,我们就能使用一个周期的时间完成读取Command(通过movx a, @dptr)和写入Repsonse(通过.db 0xa5),读写效率得到了很大提高。
CH55x-0xA5.png
另外是数据搬移的问题。CMSIS-DAP可以通过设置DAP_PACKET_COUNT的方式来提升缓冲深度,可以通过提交多条指令的方式加速处理速度。如果不在这一部分进行优化,则会花费不少时间在USB DMA地址和DAP FIFO之间搬移数据。为此,我使用了一种看似麻烦的方式,就是设置USB DMA为单缓冲,并且每读一个包就切换到下一个FIFO地址(需要处理空满情况)。考虑到全速USB的Bulk最大包大小为64Bytes,这里我设置DAP_PACKET_COUNT为4,并且确保Command和Response的FIFO对齐到整256Bytes空间。这样一来,DMA的地址可以通过对低8位的部分每次累加64得到,并且在溢出时相当于循环FIFO。由于不涉及到数据搬移,因此USB中断处理流程大大加快,并且不会干扰DAP部分的执行。
顺带一提,在我测试时CH558的USB_DMA寄存器(只读,用于表示当前DMA的传输地址)似乎有问题(似乎CH552并没有这个寄存器),会在运行一段时间后出现未知的错误结果,原因不明。在我改用端点对应的UEPx_DMA寄存器之后,问题解决。

最近编辑记录 metro (2020-02-27 20:01:46)

离线

楼主 #17 2020-02-27 20:37:18

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

ljbfly 说:

厉害,fifo地址可以随时切换吗,用关掉usb吗?

不用,CH55x有个bUC_INT_BUSY,打开之后就可以保证不清中断就自动NAK后续数据包,可以在中断直接切换。

离线

楼主 #18 2020-02-27 22:30:06

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

最后说一下SWD的时序问题以及优化方案吧。
众所周知,SWD是简单的两线协议,是ARM为Cortex-M单片机提出的优化方案。事实上,SWD的优势不仅是占用引脚少,而且传输的指令更加简单,相对而言提升了传输效率。
SWD的波形如下图所示。
swd-successful-write.png
swd-successful-read.png
swd-wait.png
swd-fault.png
swd-protocol-error.png
可以看到,SWD协议每次传输的数据包的位宽是相对固定的。对于Successful/OK的情况,可以分为以下6个阶段(空闲状态是SWCLK输出高电平,SWDIO输出高电平):

  1. 传输8-bit的command。实际上,有效数据是4个bit,Start用于指示开始,Parity用来提供4个bit的奇偶校验,Stop用于指示结束,而Park用于将引脚拉高。

  2. 第一个Turnaround,调试器切换到输入态,SWDIO暂时维持高电平。Turnaround的长度为1到4个bit,可以通过DLCR寄存器修改。

  3. 设备返回3-bit的response。一般的状态包括OK,FAULT,WAIT和Protocol Error。

  4. 对于Write而言,第4步需要切换到输出态,因此需要第二个Turnaround;对于Read而言,第4步用于输入32-bit数据及1-bit校验位。

  5. 对于Write而言,第5步用于输出32-bit数据及1-bit校验位;对于Read而言,第5步需要切换到输出态,因此需要第二个Turnaround。

  6. 第6步用于输出IDLE(如果有),简单来说就是在SWDIO输出若干个周期的低电平(直到下一个高电平时才开始下一个传输)。

这里我们先不探讨各种技术细节,可以看到SWD中8-bit的command和32-bit的data是比较规整的,而其它则比较零散。由于CH55x的SPI只能支持按字节传输,因此也只能对这两个部分优化(但是占比可以达到(8+32)/(8+5+32+1)≈87%,还是比较多的)。
当然,上文中针对的是SWD部分。由于SWJ接口(SWD和JTAG的共用接口)规定,TCK和SWCLK同一引脚,TMS和SWDIO统一引脚,并且不能修改(协议切换的逻辑只能在这两个引脚上进行),因此对于CH55x这种只有一个SPI和一组复用引脚的情况,必然只能选择其中一个协议应用SPI优化。
当然,JTAG也可以应用SPI优化,但是涉及到IR/DR切换等问题会比较复杂,等以后做到了再分享吧。

最近编辑记录 metro (2020-02-27 22:47:46)

离线

楼主 #21 2020-02-28 09:43:23

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: 晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM)

jiangming1399 说:

居然用到了汇编优化!

我想移植一个v1版本的协议到ch552,感觉对速度的要求就不是那么高了,应该就用不上这些高端的优化手段了

V1的理论最高速度就是64KB/s,毕竟HID类的限制在那。不优化理论上也是够用的。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn