nRF52のDFU試験3: Serial DFU

# 記事の概要
NordicのBLEモジュールnRF52のファームウェアを、UART通信で更新します。

今回はサンプルプログラムを用いてUART通信によるファームウェア更新ができることだけを確認します。
プログラムの解析は次回以降になります。

# Serial DFU
[nRF52のDFU試験1](https://qiita.com/Kosuke_Matsui/items/7ab5235b4cfa61a398ba)と[nRF52のDFU試験2](https://qiita.com/Kosuke_Matsui/items/ea9309ffaf75925b671e)ではアプリnRF Toolboxを用いてBLE通信でファームウェア更新を行いました。
今回はUART通信でファームウェア更新を行います。

## Dual-bank
ファームウェア更新はDual-bank方式で行います。

Dual-bankは、内蔵ROMの空きメモリをBank0とBank1に分けます。
現在走らせているアプリケーションはBank0に書き込まれており、更新したいアプリケーションはBank1に書き込みます。

アプリケーション更新時、Bank1のアプリケーションを確認後に、Bank0のアプリケーションを置き換えて更新します。

更新に失敗してもBank0のアプリケーションが引き続き走るので、更新に失敗して動作が完全に停止して、再更新もできなくなるという事態を回避できます。

欠点は使用できるメモリが半分になってしまうことです。

詳細は以下をご参照ください。
[Dual-bank and single-bank updates](https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/lib_bootloader_dfu_banks.html)

# サンプルプログラムのダウンロード
今回使用するのはNordic DevZoneの[background-dfu-application-source-code](https://devzone.nordicsemi.com/f/nordic-q-a/46994/background-dfu-application-source-code)からダウンロードできる[nRF_SDK_15.3.0_background_dfu_3.zip](https://devzone.nordicsemi.com/cfs-file/__key/support-attachments/beef5d1b77644c448dabff31668f3a47-c39136cb1d7c4b7bad35f35fd7d24c96/nRF_5F00_SDK_5F00_15.3.0_5F00_background_5F00_dfu_5F00_3.zip)です。

# サンプルプログラムのビルド

nRF_SDK_15.3.0_background_dfu_3\examples\ble_peripheral\ble_app_hrs_w_serial_dfuを開いてください。

nRF52480を使用している場合は、\examples\ble_peripheral\ble_app_hrs_w_serial_dfu\pca10056\s140\ses\ble_app_hrs_pca10056_s140.emProjectを開いてビルドしてください。

nRF52832を使用している場合は、\examples\ble_peripheral\ble_app_hrs_w_serial_dfu\pca10040\s132\ses\ble_app_hrs_pca10040_s132.emProjectを開いてビルドしてください。

# サンプルプログラムの書き込み

program_bl_sd_bl_settings_52840.batを実行すると必要なソフトデバイス、ブートローダー、上記でビルドしたアプリケーションが全て書き込まれます。

スクリプトの中身は以下のようになっています。

```
nrfutil settings generate --application pca10056/s140/ses/Output/Debug/Exe/ble_app_hrs_pca10056_s140.hex --family NRF52840 --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
nrfjprog --program settings.hex --chiperase
nrfjprog --program bootloader_hex/bootloader_w_softdevice_nrf52840.hex 
nrfjprog --program pca10056/s140/ses/Output/Debug/Exe/ble_app_hrs_pca10056_s140.hex -r
```

nRF52832を使用している場合は、program_bl_sd_bl_settings.batを実行してください。

これでUART通信でファームウェア更新する準備が整いました。

# Serial DFUの実行
ここでCOMポートに新しい接続が追加されているので、その番号を調べてください。
私の場合はCOM12でした。

前回と同じようにzipファイルを生成します。

```
nrfutil pkg generate --application pca10056/s140/ses/Output/Debug/Exe/ble_app_hrs_pca10056_s140.hex --hw-version 52 --sd-req 0xB6 --application-version 2 --key-file key/private.pem dfu_app_package.zip
```

サンプルファイルには、あらかじめ生成されたdfu_app_package.zipもあるので、それを使用することもできます。

COM12のUART通信でdfu_app_package.zipを書き込むために、anacondaで以下のコマンドを実行します。

![serial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150620/a6804105-96fe-22fc-853f-eb562d44c281.png)

書き込み成功後は、以下のようにNordic_HRMx1がスキャンできるようになっています。

![nordic_hrmx1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150620/ecec72f0-c682-d283-00f5-b0470dff0c90.png)

# 次にすること
今回のプログラムは、UART通信で取得したデータを、BANK1に書き込み、書き込み完了後にDFUモードに遷移してBANK0を上書きしています。

サーバを介したファームウェア更新は、TFTPやMQTT通信でファームウェアのデータを取得して、BANK1に書き込むように修正すればいいわけです。

今回のサンプルプログラムで、UART通信で取得したデータをBANK1に書き込んでいるのはnrf_dfu_serial.c と nrf_dfu_serial_uart.c です。
これを修正することで、目的のサーバを介したファームウェア更新を行いたいと思います。

最新のSDKへの適用、サンプルプログラムの詳細、DFUモードへの遷移方法など調査しないといけないことは大量にあるので、まだまだ先は長そうです

(追記）
サーバからファームウェア更新するには、nrfutilを使わずにDFU開始しないといけないのですが、それをするには自分でnrfutilを解析しないといけないようです。

https://devzone.nordicsemi.com/f/nordic-q-a/66097/is-is-possible-to-perform-dfu-without-the-nrfutil

https://github.com/NordicSemiconductor/pc-nrfutil