最近想做一个stm32的开源dap调试器,学习一下stm32usb的标准库用法,参考STM32_USB-FS-Device_Lib_V4.1.0实现了Custom_Hid实验,通过HID_Tool,调试发现通信成功。
由于官网最新的CMSIS 6.1.0已经去除了dap的源码,所以下载5.9.0的版本来移植dap的源码,打开工程发现是用lpcxx芯片做的,dap线程部分可以保留,要把lpcxx相关接口部分替换成STM32的接口,其中包括usb device部分和dap的io控制部分。
利用STM32_USB-FS-Device_Lib_V4.1.0库中的Custom_Hid为基础版本就可以移植dap的源码了,其中主要修改项是DAP_config.h和Dap_thread,将下图中的io改为自定义的IO。
第二步 将DAP_Thread移植过去,到这里基本可以识别到dap接口了;
其中这边set和get接口改成自定义的端点传输即可。
大概花了一周时间整理集成整个通信过程,最终实现了usb+vcp的功能,下面是本次遇到的一些问题。
1.usb设备描述符和配置描述符中的端点大小要和硬件初始化中设置的大小一致,其中STM32F103C8T6为例,支持48Mhz的全速设备传输,所以EP_SIZE 最大设置为64
2.bInterval
指定了主机轮询端点以获取新数据的间隔时间,以毫秒为单位,这项代表了usb的轮询查收的间隔,决定了dap刷写的速度
3.dap线程中识别不到目标芯片,这个时候是和系统主频和io翻转速度有关,整个dap线程都是io的操作,如果翻转速度太慢时序会跟不上目标芯片的swd速度就会识别失败。
4.vcp虚拟串口收发太慢,容易导致丢帧,由于usb传输和uart使用中断传输,收发间隔太快的话会导致大批量数据没法及时处理,使用UART DMA传输可以大大提高速率,降低丢帧概率
5.stm32的时钟问题,stm32的usb时钟必须是48MHz 是PLL直接提供,所以在主频是72Mhz情况要使能1.5倍分频