Serial Wire Debugging the STM32 via the Bus Pirate

2 October 2010

So 10 days ago I saw a post on Dangerous Prototypes mentioning the new STM32 Discovery board. Needless to say, I had impulse-bought a couple from Digi-Key within minutes. Unfortunately, I didn’t bother doing much research at that point, so I was unaware that the ST-Link has no Linux support until they arrived and I went to go program one. I could have just rebooted into Windows, but that seemed like admitting defeat, and I don’t really like IDEs anyway. Serendipitously, I had been reading about the Serial Wire Debug protocol for the past couple of days, and it seemed like a pretty nice little protocol, so I wondered if perhaps I could get that working.

Step 1 - The Bus Pirate

Given that I own a Bus Pirate, it seemed like the natural tool for implementing a new protocol that I had just read about. I had never used it before or even indeed verified that it worked, but I’ll spare you a long recounting of how I spent several days fighting with it, and just note that a tedious firmware upgrade process is ESSENTIAL if you bought a Bus Pirate from Sparkfun. Once that was fixed, it was a breeze setting up some basic serial communications with the Bus Pirate using the binary raw-wire mode from a Python script, although as mentioned in a previous post, the timings are slightly off compared to what one might naively expect.

Step 2 - Debug Port Communications

So given the ability to send and receive bits and bytes via the Bus Pirate, Debug Port communications were relatively straightforward. It’s important to pay attention to the fact that register numbers and data are all sent LSB-first down the wire, but otherwise it’s a nice, simple protocol.

Step 3 - Access Port Communications

So next I turned to the Cortex-M3 AHB Access Port, which would allow me to start manipulating the chip proper. I’ll again spare you several days of agonizing debugging, and just point out that when you clear the xPWRUPREQ bits, the associated features will power down. In hindsight, that makes a lot of sense. The general operation of the AHB-AP is pretty simple. Set the Control/Status Word to auto-increment if you want that feature, write the desired address into the Transfer Address Register, and manipulate the contents of the Data Read/Write register to your heart’s desire. At this point I was able to scan over the chip’s memory and make a dump of its contents, so I went ahead and made a copy of the current program in flash, just to be safe. This turned out to be very useful indeed.

Step 4 - Processor State

I knew that programming the flash would probably be tricky and possibly require the core to be halted, so I took some time at this point to do some little helper functions for state manipulation. Halting, unhalting, and restarting the processor are all pretty easy, simply involving writing some magic numbers to magic memory locations.

Step 5 - Programming the Flash

This stumped me for a while until I found the STM32 Flash Programming manual. After that it took some fiddling, but ultimately worked out pretty nicely. The process involves writing a sequence of keys to an unlock register before the control register can be written, then using the control register to erase the whole memory (in theory I could do it page-by-page, but that seemed harder and wasn’t necessary). Then the programming process consists of setting the FLASH_CR_PRG bit to indicate that programming is incoming, setting the AHB-AP to do writes in 16-bit packed mode, and writing the program data to memory starting at 0x08000000.

Step 6 - Optimizing

When I started this step, the script took 11 seconds to program a 3k firmware to the chip. When I finished, it took 1.5 seconds, and a good portion of that is required to avoid overflowing the write buffer (at least I think that’s the reason it errors if I try to decrease the interval between successive words). Those reads are very costly, so the optimizing essentially was just finding clever ways to avoid reading data from the Bus Pirate whenever possible, and only doing it in big blocks when required.

Conclusion

And that was it, modulo some issues with .bin file endianness and me having some trouble getting a decent firmware to compile properly. The code for the programming script, along with some precompiled firmwares which blink the blue LED at different rates, can be grabbed off GitHub, although there is currently no error recovery whatsoever, and only the most basic error detection.

Serial Wire Debugging the STM32 via the Bus Pirate的更多相关文章

  1. Introduction to Cortex Serial Wire Debugging

    Serial Wire Debug (SWD) provides a debug port for severely pin limited packages, often the case for ...

  2. Serial Wire Viewer (SWV)

    Being able to display values for counters, sensors and other debugging information is an important p ...

  3. Programming Internal Flash Over the Serial Wire Debug <SWD> Interface -- EFM32

    1 Debug Interface Overview 1.1 Serial Wire Debug Serial Wire Debug (SWD) is a two-wire protocol for ...

  4. Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors

    Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors The goal of the pro ...

  5. Serial Wire Debug (SWD) Interface -- PSoc5

    PSoC 5 supports programming through the serial wire debug (SWD) interface. There are two signals in ...

  6. SW-DP (Serial Wire Debug Port) Analyzer plugin for the Saleae Logic

    SW-DP (Serial Wire Debug Port) Analyzer plugin for the Saleae Logic The SW-DP protocol is described ...

  7. 各种版本的ST-LINK仿真器

    1.ST官方正式出版了两种仿真器:ST-LINK.ST-LINK/V2,其他型号(ST-LINK II,ST-LINK III,…)要么是国内公司生产,要么是开发板自带的:2.在ST官网ST-LINK ...

  8. KL46 custom board SWD reset is never asserted - SWS Waveform

    KL46 custom board SWD reset is never asserted Hi everybody, I'm trying to program a custom board bas ...

  9. windows下STM32开发环境的搭建

    一.概述 1.说明 笔者已经写了一篇Linux下STM32开发环境的搭建 ,这两篇文章的最区别在于开发环境所处的系统平台不一样,而其实这个区别对于开发环境的搭建其实影响不大,制作局部上的操作上发生了改 ...

随机推荐

  1. Gson学习记录

    Gson是Google开发来用来序列化和反序列化json格式数据的java库,他最大的特点就是对复杂类型的支持度高,可以完美解决java泛型问题,这得益于他对泛型类型数据的特殊处理,他的缺点就是速度慢 ...

  2. lucene删除索引——(五)

    增加在入门程序创建索引中,增删改用IndexWriter. 1.获取IndexWriter的代码 // public IndexWriter getIndexWriter() throws Excep ...

  3. SQL Server限制IP访问1433端口

    1.用系统自带的防火墙,启用防火墙 2.点击[添加端口],名称填1433,端口号填1433 3.协议TCP,点[更改范围],选自定义列表,那个框里就填本机服务器的IP地址.

  4. 初始ASP.NET数据控件【续 DataList】

    DataList控件  DataList控件也是一个常用的数据绑定控件,相对于GridView控件虽然没它那么强大的功能,但是灵活性却很强势.因为其本身就是一个富有弹性的控件.DataList控件可以 ...

  5. linux网络编程IO模型

    同步与异步:         同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成.         异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要 ...

  6. day22-23作业

    1.字节流  字符流    2.read()  3.-1  4.System.out  5.InputStream  6.OutputStream 1.IO流按流向分为输入流和输出流,即输入流和输出流 ...

  7. Linux系统产生随机数/dev/random 和 /dev/urandom

    1.  基本介绍 /dev/random和/dev/urandom是Linux系统中提供的随机伪设备,这两个设备的任务,是提供永不为空的随机字节数据流.很多解密程序与安全应用程序(如SSH Keys, ...

  8. java 异常使用指南

    应该在以下情况使用异常: 1.)在恰当的级别处理问题.(在知道如何处理的情况下才捕获异常) 2.)解决问题并且重新调用异常的方法 3.)进行少许的修补,然后绕过异常发生的地方继续执行 4.)用别的数据 ...

  9. Java 在方法和作用域内的内部类

    通常,如果所读写 的代码包含了内部类,那么它们都是"平凡的"内部类,简单并且容易理解,然而,内部类的语法覆盖了大量其它的更加难以理解的计数,例如可以在一个方法里或者在任意的作用域里 ...

  10. Laravel 的 JSON API 接口自动化测试

    Laravel 自带了两种测试类型 Feature Test: 功能测试.针对类似接口这种流程性的测试. Unit Test: 单元测试.针对单个函数这种输入输出结果的测试. 新建一个 Feature ...