GCCビルドに対応したDAPLinkでカスタムボードを使う

Mbed OS対応デバイスやmicro:bit等でターゲットマイコンに書き込むための仕組みとして使われているDAPLinkですが、最近GCCでのビルドにも対応しました（詳しくは[こちら](https://qiita.com/toyowata/items/cc8105d88b44c90ba0b0)をご覧ください）。

この記事では、GCCに対応したDAPLinkを使って、カスタムボード用のポーティングを行う手順を紹介します。

https://github.com/ARMmbed/DAPLink

DAPLink本家のリポジトリは、以前から自分のアカウントでフォークして使っていましたが、現在のDAPLinkのGCC対応がdevelopブランチで作業されているため、フォークした自分のリモートリポジトリでこのブランチをベースにして作業をしたいと思ったのでした。

## 開発用ブランチの作成

フォーク元の（新しく作られた）ブランチを自分のリモートリポジトリに取り込む方法がよく分かっていなったので、こちらの情報を参考にしました。

https://www.zunouissiki.com/entry/2019/01/06/074419/

まず、自分のリモートリポジトリを最新版に追従しておきます。

```
$ git clone https://github.com/<your_account>/DAPLink
$ cd DAPLink
$ git remote add upstream git@github.com:armmbed/daplink.git
$ git fetch upstream
$ git merge upstream/main
$ git push
```

次にフォーク元ブランチ（本家）のdevelopブランチを取り込んで、リモートリポジトリにpushします。

```
$ git fetch upstream
$ git checkout -b develop upstream/develop
$ git push origin develop
```

これで、developブランチが出来ました。これをベースにした開発ブランチを作成します。

```
$ git checkout -b dev_gcc-custom_boards
$ git branch
* dev_gcc-custom_boards
  develop
  master
```

これのブランチにカスタムボードのポーティングを追加します。適宜、フォーク元のdevelopブランチの変更を取り込んで最新版にすることも出来ます。

## 事前準備

まず、DAPLinkをビルドできる環境をセットアップします。私は、macOS Monterey 12.2 を使いましたが、Windowsでもそれほど違いはないと思います。

- arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 (release)
- python 3.9.5

```
$ cd DAPLink
$ pip3 install -r requirements.txt
```

次に、適当なボード用のDAPLinkファームウェアをビルドしてみます。

```
$ python3 tools/progen_compile.py -t make_gcc_arm lpc11u35_ssci1114_if
```

エラーなくビルドが実行され、バイナリファイルが生成されれば成功です。

```
$ ls projectfiles/make_gcc_arm/lpc11u35_ssci1114_if/build/*.bin
projectfiles/make_gcc_arm/lpc11u35_ssci1114_if/build/lpc11u35_ssci1114_if.bin
projectfiles/make_gcc_arm/lpc11u35_ssci1114_if/build/lpc11u35_ssci1114_if_crc.bin
```

## カスタムボードのポーティング

DAPLinkでは、インタフェース側とターゲット側のマイコンの組み合わせでポーティング作業を考える必要があります。詳しくは公式のドキュメントを参考にしてください。
https://github.com/ARMmbed/DAPLink/blob/main/docs/DEVELOPERS-GUIDE.md#port

今回ポーティングに使用したカスタムボードは、インタフェース側のHICは対応済みで、ターゲット側マイコンとボードが新規登録になります。主に以下のような作業になります。

* project.yaml にプロジェクトの追加
* records/board 配下にカスタムボードを追加
* source/board 配下にボード定義とオーバーライドしたIOピン定義を追加
* source/family 配下にflash書き込みコードとターゲット定義を追加

使用するターゲット側マイコンが既にポーティング済みで、ピンアサインのみ変更する場合は作業は若干簡略されます。

今回カスタムボードにポーティングしたコードを例に紹介します。

### project.yamlにプロジェクトの追加

プロジェクト名称は、`<インタフェース名>_<ターゲット名>_if` という表記が推奨されているようです。他のプロジェクトを参考にして、`lpc11u35_ae_lpc11u35_mb_if` を追加します。

https://github.com/toyowata/DAPLink/commit/d997d35ec71e69e6c49edd4f7b6f24b66b32b48a#diff-c555c2ae2d562d803bbdaade7a50e3774161e1c51623309302f91a87b598085c

### records/board 配下にカスタムボードを追加

上記プロジェクト定義で指定したファイルを作成します。IOピンをオーバーライドする必要があったので、IO_CONFIG_OVERRIDEマクロとインクルードパスの追加を行っています。

https://github.com/toyowata/DAPLink/commit/d997d35ec71e69e6c49edd4f7b6f24b66b32b48a#diff-e5538b3d39c0160a983c6bcf841caaf652c7a6371444a5ba99e00fa44846ff1a

### source/board 配下にボード定義とオーバーライドしたIOピン定義を追加

g_board_info構造体を定義します。board_idは任意ですが、Mbed OS対応ボードなどと重ならないようにした方が良いと思います。

https://github.com/toyowata/DAPLink/commit/d997d35ec71e69e6c49edd4f7b6f24b66b32b48a#diff-dabbdc0c605da1ee388096d6b3432f236e0f821d708b0e16fd6c0320dc57489b

因みにですが、Mbed OS対応ボードのIDは、こちらに登録されています。
https://github.com/ARMmbed/mbed-os-tools/blob/master/src/mbed_os_tools/detect/platform_database.py

IOピンの定義は、以下です。インタフェース側のマイコンで使用する（ターゲット側と接続する）ピンを設定します。

https://github.com/toyowata/DAPLink/commit/d997d35ec71e69e6c49edd4f7b6f24b66b32b48a#diff-cc2a27c2edb3a8ab42f72c7c781b855d948d844a4cf83dd9571ef9a65259b6b0

### source/family 配下にflash書き込みコードとターゲット定義を追加

ターゲットマイコンのフラッシュメモリに書き込むためのバイナリコード（フラッシュ書き込みアルゴリズム）を配置します。このコードは、インタフェース側マイコンのRAM上で実行されます。

https://github.com/toyowata/DAPLink/commit/d997d35ec71e69e6c49edd4f7b6f24b66b32b48a#diff-13e73918991e02ee869be27b0107315e23c097515d79885f8e7c70647dc4fa3a

なお、このフラッシュ書き込みコードを生成するためのプログラムは、こちらで公開されています。

https://github.com/pyocd/FlashAlgo

最後にターゲットマイコンのメモリサイズなどの定義を追加します。

https://github.com/toyowata/DAPLink/commit/d997d35ec71e69e6c49edd4f7b6f24b66b32b48a#diff-d5def82fcd08476317de388ecbba8812e6f09796e1c2f713f743f3f1aa613b97

### カスタムボード用DAPLinkのビルド

今回作成したカスタムボード用のDAPLinkは、以下のコマンドでビルドします。

```
$ python3 tools/progen_compile.py -t make_gcc_arm lpc11u35_ae_lpc11u35_mb_if
```

ビルドが成功すると、`projectfiles/make_gcc_arm/lpc11u35_ae_lpc11u35_mb_if/build/lpc11u35_ae_lpc11u35_mb_if_crc.bin` が生成されるので、これをカスタムボードのインタフェース側マイコンに書き込みます。

以上です。