swddudeをMac OS Xで使ってみた

かなり前に[swddude](https://github.com/cbiffle/swddude)というSWDなツールを見つけていたのだが、動作させる事ができなくてあきらめていたのだが、ちょっと思いついていじってみて、使えるようになったのでメモを残しておきます。

SWDとはJTAGを2本の信号線だけで使えるようにしたものです。LPC810などではJTAGの本数分のPINを使えないためにJTAGではなくSWDを使う事になります。ちなみにLPC810などはSWD以外にシリアルを使ったISPでのFlashの書き込みも可能です。

swddudeはかなり大きなライブラリコードとビルドシステムの上に作られていて、当初gitにあるソースをrecursiveにcloneする必要があるのを知らず、ごにょごにょしてビルドを通したのですが、うまく動かなくて何が悪いのか分からなくなったのもあきらめた原因でした。

gitのレポジトリをrecursiveでcloneします。

依存で面倒な事が起きないように、/usr/local/にはできるだけファイルを置かないようにしています。このためローカルにライブラリを置いてビルドをおこないます。

swddudeはlibftdiとlibusb-1.0を必要としているので、これらのライブラリを用意します。用意できたらsource/Makefileに以下のようにヘッダーとライブラリのありかを指定します。元はlinuxなどのpackageを前提にしていて、そこから読み出すようにしているようです。

```
swddude[cpp_flags]      := -I../
swddude[l_flags]        := -L../ -lftdi -lusb-1.0
```

libusbはconfigureですがlibftdiはcmakeで、面倒なので自力でビルドします。

```
$ cd src
$ sed 's/@MAJOR_VERSION@/1/;s/@MINOR_VERSION@/4/;s/@.*@//' ftdi_version_i.h.in  
 > ftdi_version_i.h
$ cc -I../../libusb-1.0.19/libusb/ -c *.c
$ ar r libftdi.a *o
ar: creating archive libftdi.a
```

上記はライブラリとヘッダーファイルをディレクトリの一番上にコピーしてあります。libusbはdylibでないとだめだったので、コピーしてパスを書き換えています。

```
bash-3.2$ ls
Makefile                ftdi.h                  libusb.h
README.md               libftdi.a               source
build                   libs
examples                libusb-1.0.dylib
bash-3.2$ install_name_tool -id @executable_path/../../libusb-1.0.dylib libusb-1.0.dylib
````

これでmakeするとdprintfなどいくつかMac OS Xにはない関数をつかっていてリンクエラーになるので、ダミーの関数を用意します。

追記：上記の修正をおこなったレポジトリ作りました。 https://github.com/yamori813/swddude

ビルドが通るとsource/release/の下にいくつかのバイナリファイルができます。

FT2232HとLPC1114で試してみたのですが、接続は以下のようにおこないます。

![FTDISWD.png](https://qiita-image-store.s3.amazonaws.com/0/104066/e2e05404-8a6f-089d-883c-2e5026923927.png)

これで。swdprobeを実行してみます。FT2232Hの場合-programmer bus_blasterを指定します。

```
bash-3.2$ source/release/swdprobe -programmer bus_blaster
 Notice..: SWD communications initialized successfully.
 Notice..: SWD-DP IDCODE = 0BB11477
 Notice..:   Version:   0
 Notice..:   Part:      BB11
 Notice..:   Designer:  23B
 Notice..: Scanning for connected Access Ports...
 Notice..: Access Port #0: IDR = 04770021
 Notice..:   Found MEM-AP.
 Notice..: CPU is Cortex-M0 r0p0
 Notice..: Device @E00FF000
 Notice..:   Device is ROM table: 4096 bytes
 Notice..: Device @E000E000
 Notice..:   Component is ARMv6M SCS
 Notice..: Device @E0001000
 Notice..:   Component is ARMv6M DWT
 Notice..:   DWT comparator count   : 2
 Notice..: Device @E0002000
 Notice..:   Component is ARMv6M BPU
 Notice..:   Breakpoint count: 4
 Notice..:   Literal watchpoint count: 0
```

試しにmbedでビルドしたバイナリを焼いてみました。

```
bash-3.2$ source/release/swddude -programmer bus_blaster -flash ~/Downloads/mbed_blinky_LPC1114.bin -fix_lpc_checksum
 Notice..: Target supports 4 hardware breakpoints.
 Notice..: Contents of Flash:
 Notice..:  [00000000] 10001000
 Notice..:  [00000004] 0000021D
 Notice..:  [00000008] 0000022F
 Notice..:  [0000000C] 00000225
 Notice..:  [00000010] 00000000
 Notice..:  [00000014] 00000000
 Notice..:  [00000018] 00000000
 Notice..:  [0000001C] EFFFE98F
 Notice..:  [00000020] 00000000
 Notice..:  [00000024] 00000000
 Notice..:  [00000028] 00000000
 Notice..:  [0000002C] 00000227
 Notice..:  [00000030] 00000000
 Notice..:  [00000034] 00000000
 Notice..:  [00000038] 00000229
 Notice..:  [0000003C] 0000022B
 Notice..:  [00000040] 0000022F
 Notice..:  [00000044] 0000022F
 Notice..:  [00000048] 0000022F
 Notice..:  [0000004C] 0000022F
 Notice..:  [00000050] 0000022F
 Notice..:  [00000054] 0000022F
 Notice..:  [00000058] 0000022F
 Notice..:  [0000005C] 0000022F
 Notice..:  [00000060] 0000022F
 Notice..:  [00000064] 0000022F
 Notice..:  [00000068] 0000022F
 Notice..:  [0000006C] 0000022F
 Notice..:  [00000070] 0000022F
 Notice..:  [00000074] 0000022F
 Notice..:  [00000078] 0000022F
 Notice..:  [0000007C] 0000022F
 Notice..:  [00000080] 0000022F
 Notice..:  [00000084] 0000022F
 Notice..:  [00000088] 0000022F
 Notice..:  [0000008C] 0000022F
 Notice..:  [00000090] 0000022F
 Notice..:  [00000094] 0000022F
 Notice..:  [00000098] 0000022D
 Notice..:  [0000009C] 0000022D
 Notice..:  [000000A0] 0000022F
 Notice..:  [000000A4] 0000022F
 Notice..:  [000000A8] 0000022F
 Notice..:  [000000AC] 0000022D
 Notice..:  [000000B0] 0000022F
 Notice..:  [000000B4] 0000022F
 Notice..:  [000000B8] 0000022F
 Notice..:  [000000BC] 0000022F
 Notice..:  [000000C0] FFFFFFFF
 Notice..:  [000000C4] FFFFFFFF
 Notice..:  [000000C8] FFFFFFFF
 Notice..:  [000000CC] FFFFFFFF
 Notice..:  [000000D0] FFFFFFFF
 Notice..:  [000000D4] FFFFFFFF
 Notice..:  [000000D8] FFFFFFFF
 Notice..:  [000000DC] FFFFFFFF
 Notice..:  [000000E0] FFFFFFFF
 Notice..:  [000000E4] FFFFFFFF
 Notice..:  [000000E8] FFFFFFFF
 Notice..:  [000000EC] FFFFFFFF
 Notice..:  [000000F0] FFFFFFFF
 Notice..:  [000000F4] FFFFFFFF
 Notice..:  [000000F8] FFFFFFFF
 Notice..:  [000000FC] FFFFFFFF
```

20秒くらいで焼けました。

HISpeedなMPSSEがサポートされたFTDIのチップでしか使えませんが、ちょっと便利かもしれません。

試したMacはMBA Originalの雪豹です。最近のMacは持っていないので試していません。


追記

LPC1343をプローブ

```
bash-3.2$ source/release/swdprobe -programmer  um232h
 Notice..: SWD communications initialized successfully.
 Notice..: SWD-DP IDCODE = 2BA01477
 Notice..:   Version:   2
 Notice..:   Part:      BA01
 Notice..:   Designer:  23B
 Notice..: Scanning for connected Access Ports...
 Notice..: Access Port #0: IDR = 24770011
 Notice..:   Found MEM-AP.
 Notice..: CPU is Cortex-M3 r2p0
 Notice..: Device @E00FF000
 Notice..:   Device is ROM table: 4096 bytes
 Notice..: Device @E000E000
 Notice..:   Component is ARMv7M SCS
 Notice..: Device @E0001000
 Notice..:   Component is ARMv7M DWT
 Notice..:   DWT comparator count   : 4
 Notice..:   Tracing/sampling       : Supported
 Notice..:   External match signals : Supported
 Notice..:   Cycle counter          : Supported
 Notice..:   Profiling counters     : Supported
 Notice..: Device @E0002000
 Notice..:   Component is ARMv7M FPB
 Notice..:   Breakpoint count: 6
 Notice..:   Literal watchpoint count: 2
 Notice..: Device @E0000000
 Notice..:   Component is ARMv7M ITM
 Notice..: Device @E0040000
 Notice..:   Component is ARMv7M TPIU
 Notice..: Device @E0041000
 Notice..:   Component is ARMv7M ETM
```

LPC1343はあまり安定していないようです。ビルド環境がないので、書き込みは試していません。

LPC810でも使えるようにしてみました。swdprobeはエントリーを追加しただけですが、swddudeは何故かcopy_ram_to_flashのIAPでエラーになっていました。いろいろ調べたところ、ねむいさんのぶろぐにLPC81xはスタックがLPC11xxより多く必要という事が書いてあり、スタックを128バイトから256バイトに修正したところ問題なく動作するようになりました。あとセクターのサイズとブロックサイズも調整してあります。チップ毎のセクターのサイズはlpc21ispのデータを流用できるようにいじっています。SWDを試したのはトラ技のLPC810の基板をためでした。

![写真（2017-03-29 19.19）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/8f86aa74-ef6d-b681-8d6d-16c7d753467f.jpeg)

```
bash-3.2$ release/swdprobe 
 Notice..: SWD communications initialized successfully.
 Notice..: SWD-DP IDCODE = 0BC11477
 Notice..:   Version:   0
 Notice..:   Part:      BC11
 Notice..:   Designer:  23B
 Notice..: Scanning for connected Access Ports...
 Notice..: Access Port #0: IDR = 04770031
 Notice..:   Found MEM-AP.
 Notice..: CPU is Cortex-M0 r0p0
 Notice..: Device @E00FF000
 Notice..:   Device is ROM table: 4096 bytes
 Notice..: Device @E000E000
 Notice..:   Component is ARMv6M SCS
 Notice..: Device @E0001000
 Notice..:   Component is ARMv6M DWT
 Notice..:   DWT comparator count   : 2
 Notice..: Device @E0002000
 Notice..:   Component is ARMv6M BPU
 Notice..:   Breakpoint count: 4
 Notice..:   Literal watchpoint count: 0
bash-3.2$ release/swddude -flash ../../LPC810_CodeBase-master/src/blinky.bin  -fix_lpc_checksum
 Notice..: Target supports 4 hardware breakpoints.
 Notice..: Contents of Flash:
 Notice..:  [00000000] 10000104
 Notice..:  [00000004] 000000CB
 Notice..:  [00000008] 000000C1
 Notice..:  [0000000C] 000000C3
 Notice..:  [00000010] 00000000
 Notice..:  [00000014] 00000000
 Notice..:  [00000018] 00000000
 Notice..:  [0000001C] EFFFFCAD
 Notice..:  [00000020] 00000000
 Notice..:  [00000024] 00000000
 Notice..:  [00000028] 00000000
 Notice..:  [0000002C] 00000000
 Notice..:  [00000030] 00000000
 Notice..:  [00000034] 00000000
 Notice..:  [00000038] 000000C5
 Notice..:  [0000003C] 000000C7
 Notice..:  [00000040] 000000C9
 Notice..:  [00000044] 000000C9
 Notice..:  [00000048] 00000000
 Notice..:  [0000004C] 000000C9
 Notice..:  [00000050] 000000C9
 Notice..:  [00000054] 000000C9
 Notice..:  [00000058] 00000000
 Notice..:  [0000005C] 00000000
 Notice..:  [00000060] 000000C9
 Notice..:  [00000064] 000000C9
 Notice..:  [00000068] 00000225
 Notice..:  [0000006C] 000000C9
 Notice..:  [00000070] 000000C9
 Notice..:  [00000074] 000000C9
 Notice..:  [00000078] 00000000
 Notice..:  [0000007C] 000000C9
 Notice..:  [00000080] 00000000
 Notice..:  [00000084] 00000000
 Notice..:  [00000088] 00000000
 Notice..:  [0000008C] 00000000
 Notice..:  [00000090] 00000000
 Notice..:  [00000094] 00000000
 Notice..:  [00000098] 00000000
 Notice..:  [0000009C] 00000000
 Notice..:  [000000A0] 000000C9
 Notice..:  [000000A4] 000000C9
 Notice..:  [000000A8] 000000C9
 Notice..:  [000000AC] 000000C9
 Notice..:  [000000B0] 000000C9
 Notice..:  [000000B4] 000000C9
 Notice..:  [000000B8] 000000C9
 Notice..:  [000000BC] 000000C9
 Notice..:  [000000C0] E7FEE7FE
 Notice..:  [000000C4] E7FEE7FE
 Notice..:  [000000C8] B508E7FE
 Notice..:  [000000CC] FA28F000
 Notice..:  [000000D0] 4B0A2200
 Notice..:  [000000D4] 18D3490A
 Notice..:  [000000D8] D204428B
 Notice..:  [000000DC] 58894909
 Notice..:  [000000E0] 60193204
 Notice..:  [000000E4] 4B08E7F5
 Notice..:  [000000E8] 42934A08
 Notice..:  [000000EC] 2200D202
 Notice..:  [000000F0] E7F9C304
 Notice..:  [000000F4] F81CF000
 Notice..:  [000000F8] 46C0E7FE
 Notice..:  [000000FC] 10000000
```

copy_ram_to_flashを実行するときには下記のようにSRAMにデータを保存しています。

![LPC-IAP.png](https://qiita-image-store.s3.amazonaws.com/0/104066/4ef57f5d-3f5d-072b-2e14-4a11f3f357b7.png)

Block bufferにデータをコピーしてIAP parameterにコピー元のBlock bufferのアドレスすなわち0x1000 0000とコピー先のFlashのアドレスを入れて、実行するときにSPにSTACKの最上位アドレスを入れています。