GPIO 访问 SWD 接口的心得体会

2019-12-10 18:20发布

本帖最后由 helislayer 于 2016-6-23 22:30 编辑

最近写了些用 GPIO 访问 swd 的程序来玩。记录一下体会:

1)ARM Debug Interface Architecture Specification 这个是 ARM
给的规范,初学不要去读。用这个上手极其困难。这个规范讲了
太多细节,很多常识性的东西没有讲。例如我一直疑惑 turn around
的时候是谁驱动 swclk,应该是 host 但是没有说。这个规范比较
适合已经把底层跑通了,看细节某个寄存器如何用的。适合做 ARM
的厂家不适合作为程序员来写个 swd 访问的程序。

2)上手收建议这个:EFM32: Programming Internal Flash
Over the Serial Wire Debug Interface。
这个手册是从如何写 SWD 接口程序的,虽然不是 STM32 的,
但是比较清楚,例如我前面的疑惑就讲很明白。这个手册也不长。
我上传上来了。

3)那个 SWD 接口其实就是和 SPI 非常像,基本上可以理解为
MOSI 和 MISO 合并成一根线SWD-IO。中间有软件协议上下文来
协商谁来驱动这根线。这个转换需要一个 clock, 就是 turn around。

4) 那个 SWD 的 CLK 就是 SPI CLK, 永远由 host 来驱动。

5)target 永远再上升沿采集和放新的数据。这个意味着 host 从
target 读数的时候是在下降沿读比较方便。

6)思路和攻略大概是这样,要先写个底层的接口可以 reset。
就是发一堆 1 (50 以上) 和 中间发一个 0xE79E 再发 50 多个 1.
0xE79E 就是说老子要用 SWD 而不是 JTAG。

7)接下来就要写 读写 AP 和 DP 的寄存器。每种一共 4 个地址很简单。
这个 DP 就是调试接口的硬件。这个 AP 就是一个访问周边外设和内存
的硬件接口。因为 ARM 的外设都是影射到内存地址的,所以可以访问
任意内存地址就可以刷程序和调试了。

8)访问内存需要通过 AP。就是先写访问内存的地址到一个地址寄存器,
然后通过另外一个数据寄存器读写内存。

大概就是这样,我先在也就只是做到这一步。



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
98条回答
helislayer
1楼-- · 2019-12-13 10:47
最近又研究了一下如何把程序通过 swd 写到 flash 里面。
swd 并没有特别的写 flash 的支持。写 flash 是一般有两个策略。

第一个直接通过 AP 在 stm32 是 AHB-AP 来写 flash 的寄存器。
这个和在程序里面写 flash 步骤是一样的,要先写 Key 解锁 flash
等等。不同的是,利用 swd 的 AP 访问来完成寄存器读写。
例如, C 里面的 FLASH->CR = 1

在 SWD 就要分两步,
1)为了写一个寄存器,需要先写 AP 的 TAR 寄存器放入 FLASH->CR
的地址。
2)然后写 AP 的 DRW 寄存器,放入 1。

读就更麻烦了,因为 AP 寄存器读是上个周期的数据,为了拿到新
的数据要读两次。所以 C 里面 a = FLASH->CR 这个简单操作,
等价的 swd 步骤是:
1)AP 的 TAR 写入 FLASH->CR 的地址。
2)AP 的 DRW 读入一个数据,这个数据是上次产生的,扔掉。
这个时候 AP 去读 AHB 的内存,DRW 已经被更新了,但是我们
没有见到新的数据。
3)AP 的 RDBUFF 读入一个数据。这个数据就是上次 DRW 读入
那个。为什么不去读 DRW 呢?读 DRW 也能拿到同样的数,但是
TAR 有可能会自动增加,如果你打开了 CSW 里面的自动增加机制。
相比之下读 RDBUFF 就不会修改 TAR。

好了,可以看见读一个32位值很麻烦,需要三个 swd request。
然后写flash 的时候需要不断的读 flash 的busy 状态才能知道可以
写下一个 flash。这个就很亏,因为写一个 flash word 需要好几个
swd 操作。 也就是说,下载速度会比较慢。


然后自然就有了第二个策略,就是先把要 flash 的内容放到 ram
里面,然后在 ram 里面跑个循环把 flash 写进去。这样就不用反复
在 swd 上来查 flash 的 busy 状态。这种做法 swd 上传输的数据可以
和需要 flash 的数据差不多,而不是 几个倍数的关系。因为前面提到
TAR 有个自动增加机制,写 RAM 就一股脑灌 DRW 就行了。

如果要用这个策略,问题马上来了,如何装程序进去到 ram 里面?
和装flash 数据一样。

那如何让程序跑起来?这个就要用到 STM32 的 CoreDebug 调试外设。
CoreDebug 在手册里有提到一下,头文件也有。 CoreDebug 就可以
halt, run 一个程序,改 PC R1 R2 寄存器这些。

helislayer
2楼-- · 2019-12-13 11:27
helislayer 发表于 2016-6-25 14:17
最近又研究了一下如何把程序通过 swd 写到 flash 里面。
swd 并没有特别的写 flash 的支持。写 flash 是一 ...

直接闪存编程如何做的,  STM32闪存写入是16位, SWD通信是32位。   
huangqi412
3楼-- · 2019-12-13 15:35
huangqi412 发表于 2016-6-25 15:55
直接闪存编程如何做的,  STM32闪存写入是16位, SWD通信是32位。

AP 访问的第一个寄存器 CSW 可以设定 TAR 是否自动增长和 DRW 访问的位数。在那里设置16位就可以用16位访问。虽然DRW是32的。
helislayer
4楼-- · 2019-12-13 19:29
helislayer 发表于 2016-6-25 20:04
AP 访问的第一个寄存器 CSW 可以设定 TAR 是否自动增长和 DRW 访问的位数。在那里设置16位就可以用16位访 ...


我回头看看  依然写32位数据但是高16位忽略无效对吧   好久前也搞过swd和jtag. 后面忘记了  有人问我这个 我也不知道了
huangqi412
5楼-- · 2019-12-14 00:14
 精彩回答 2  元偷偷看……
helislayer
6楼-- · 2019-12-14 03:31
helislayer 发表于 2016-6-25 14:17
最近又研究了一下如何把程序通过 swd 写到 flash 里面。
swd 并没有特别的写 flash 的支持。写 flash 是一 ...

keil下载程序就是用后一种办法,放一段小程序到sram

一周热门 更多>