Wuxy Robot Dev Engineer

SWD离线下载研究

2019-01-03
wuxy

声明

本文的标签是编整,大部分的研究内容都是我从网上收集而来,加上我的理解和整理而成,在引用他人的研究内容时,我会注明出处,如有侵权,请联系作者。

本文的研究内容全部开源,可以用于学习,研究,商用,商用时请注明出处。

课题背景

单片机通常有2种下载方式,IAP(in application programming,在应用编程)和ISP(in system programming,在系统编程)。SWD就是典型的IAP编程,SWD还支持在线调试等功能,是一个被广泛使用的下载方式,只需要3线就能实现,即:CLK,IO,GND。现有的常用下载方式都是用PC端通过Jlink/STLink给目标板下载程序,虽然下载调试都比较方便,但是每次都需要连接电脑,在部分场合不是很方便,所以提出了SWD离线下载的研究。

研究意义

SWD离线下载器可以方便工厂批量下载,可以作为技术支持人员的手持下载设备,也可以作为研发人员的下载器,如果再添加无线模块便可以实现无线下载。

一个基于STM32的乞丐原始版SWD离线下载器MDK工程

参考链接:贴一个基于STM32的乞丐原始版SWD离线下载器MDK工程

一只想做一个基于STM32的SWD离线下载器,奈何网上没有一个基于STM32的开源的(主要原因是自己菜)。

坛子里面有许多人做出来的,我曾经发私信问过好几个坛友,希望能够咨询一下,不过没有一个人回复我…尴尬……..

看过基于STM32F103的daplink(就是那个支持拖拽下载的)的源代码,也看过cmsis daplink,程序太复杂了,初学者很难剥离出需要的代码来修改为离线下载器。自己之前也大致研究过这个,也只能是做到读取DP,AP,读取寄存器的程序,今天逛github,发现了一个驱动代码,于是我结合以前我写的代码,也移植了 一些别人的代码,勉强调通了SWD程序下载。 程序是基于STM32c8t6小板做的,还没有做外界FLASH或EEPROM来存程序,只是将一个简单的程序转换为数组,存入单片机的中的。这个其实算不上离线下载器,但是改动一下,作为一个乞丐版的离线下载器还是可以的。 只对STM32F103RCT6进行了测试,目标程序运行正常。

最后贴上MDK工程 同时希望有兴趣的坛友可以继续完善一下,如果您改进了这个程序,恰巧您高兴,可以贴出源代码到这个帖子,或许能够做成第一个开源的离线下载器。 如果没人后续改进,我自己也会慢慢抽时间改进。。这个过程可能很长。。

网盘链接:https://pan.baidu.com/s/1yZ3mPvbIUZMwV83TYl05kw 密码:3cqx

分享离线SWD编程器代码

参考链接:分享离线SWD编程器代码

SWD离线编程器,其实很简单,, 因为关键代码国外的大侠都已经给实现了,,我们只需要简单拼接一下就OK啦

下面我就说下怎样通过拼接代码实现离线编程器:

1、首先,既然是SWD编程器,那首先当然是要实现SWD时序协议了 由于单片机都没有SWD外设,所以只能用GPIO模拟实现SWD时序,,这部分功能已经由ARM公司的CMSIS-DAP代码实现

2、然后就是基于CMSIS-DAP,实现通过DAP读写目标芯片的内存、内核寄存器,,这部分功能已经由DAPLink里面的swd_host.c文件实现

同时,swd_host.c还实现了另一个对实现编程器至关重要的函数:

    uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4)

它的作用是通过DAP在目标芯片上执行

那么,我们只要把编程算法(一段在目标芯片上执行的代码,里面有Flash_Erase、Flash_Write两个函数)通过SWD写入目标芯片的SRAM,然后再通过SWD调用目标芯片SRAM里面的Flash_Erase、Flash_Write两个函数,不就能实现通过SWD给目标芯片编程了吗??

所以,程序的主体结构就是:

其中target_flash_init()的主要作用就是把芯片的编程算法下载到目标芯片的SRAM中去.

好了,SWD编程器已经实现.

不过还有一个问题:要下载到目标芯片SRAM中去的编程算法从哪里来??

我们知道,Keil针对每一颗芯片都有一个Flash编程算法,这个算法存在一个后缀为.FLM的文件里面,,要是我们能把.FLM文件里面的算法内容抽取出来给我们用,,那不就完美了吗

3、其实这个功能也已经有国外大神给实现了,GitHub上的FlashAlgo项目里面有个flash_algo.py文件,它就是用来实现这个功能的

工程示例代码:

另外,这个工程我也已经上传到github上了,,希望坛友能顺便去给加个星,,谢谢啦. https://github.com/XIVN1987/DAPProg

Keil_v5\ARM\Flash_Template目录下有个烧录算法模板,,其中部分函数如下:

对比SWD_flash.c的代码发现一些问题: 1、Keil算法中的函数都是正确返回0、错误返回1,而SWD_flash.c认为函数返回0表示出错 2、Keil算法中Init函数的第三个参数说明,Init函数应该是在Erase、Program、Verify之前各分别执行一次,,而SWD_flash.c的实现只在最开始(也就是Erase之前)调用一次Init

所以,很可能SWD_flash.c不是针对Keil的编程算法写的,,DAPLink项目可能实现了自己的编程算法接口,,而我上面那个STM32的Demo之所以能执行成功,可能是因为: 1、所有函数都没检查返回值, 2、可能在STM32的编程算法中Init函数对Erase、Program、Verify这三个操作执行的内容是一样的,,所以执行一遍Init就行了

不过用在另一些芯片上可能就不行了

所以,我对SWD_flash.c做了一些修正,,不过由于没有板子,暂时没法测试,,感兴趣的坛友可用试一下。

另外如果想实现在线编程器的话,其实GitHub上也有现成的代码可用参考:https://github.com/mbedmicro/pyOCD

在这个项目下有个叫flash.py的文件,其中部分函数如下:

是不是看起来和SWD_flash.c中的函数非常像啊 ,,有了这个文件,实现在线编程器就So Easy了!!

不过也有两个小问题: 1、这个项目是基于CMSIS-DAP(DAPLink)的,如果想用JLink做在线下载的话,需要把底层部分换成jlink.py 2、这是个命令行的项目,想要做个带图形界面的在线下载器的话,需要自己添加GUI功能

继续填坑

下面两段内容分别来自flash_algo.py和c_blob.tmpl

整个编程烧写过程占用了目标芯片4K SRAM,其中SRAM起始地址为0x20000000,栈顶指向4K SRAM的末尾,,编程算法占用4K SRAM的前1K,,待烧写数据占用4K SRAM的中间2K,,静态变量和栈共用4K SRAM的最后1K

这种设计对绝大多数Cortex-M芯片是没有问题的,,不过有几种情况可能需要调整红线框住的部分: 1、SRAM的起始地址不是0x20000000,这种调整最简单,把entry的值调整成正确值就可用了 2、单片机的SRAM小于4K,这种就比较麻烦,得根据实际情况重新规划SRAM的分配,,然后红线框住的部分可能都要改动 3、编程算法内容大于1K,,有些使用片外SPI Flash的芯片它的编程算法会非常大,1K SRAM装不下,,这种把后面几个部分的地址都往后延就行了

所以,对于有些比较特殊的芯片,,需要先修改一下flash_algo.py和c_blob.tmpl,然后再生成算法文件对应的.c文件,,不过还好,生成是一次行的,,

随便一个STM32F103C8的demo板就行,,模拟SWD用的B13、B14两个引脚

参考阅读

拓展阅读


Comments

Content