前提
- nrf5Xの開発を行っている
- OTAをしたい(Bluetooth経由でアプリケーションをアップデートしたい)
- Segger Embedded Studioを使う
- OSXで開発
公式ガイド
ここみれば一応解決はします。
背景
- nrf52で開発しているとやはりFirmware OTA(Over-the-air)はしたい。
- そもそもOTAで見ず知らずのアプリケーションを書き込めるのは嫌だ
- SDK12以降はsecureじゃないDFUはできない1
やること
- secure bootloaderを書き込む
- アプリケーションに署名をする
1.secure bootloaderを書き込む
事前準備もろもろ必要なもののインストール
ひつようなもの
- homebrew
- https://qiita.com/krtsato/items/ba567acacb93a7a02dd9
- python2
- pip
- nrf5 SDK
- nrfutil
- arm toolchain
- μECC(https://github.com/kmackay/micro-ecc)
- Segger Embedded Studio
nrf5 SDK
https://www.nordicsemi.com/?sc_itemid=%7B21C26716-5F2C-4E2D-9514-C9B87B711114%7D
ココからダウンロードし、解凍。
nrfutilのインストール
キーペアの作成、SDK用コードへの変換、署名に利用するツールです。
pythonの動作環境と、pipが必要です。
なお、nrfutilはpython2のみ対応。3
- version 6.00でpython3サポートがされたようです。(https://github.com/NordicSemiconductor/pc-nrfutil/releases/tag/v6.0.0)
$ pip install nrfutil
arm toolchainダウンロード
- bootloaderのコンパイルというよりは、後述のmicroeccのコンパイルに利用します。
$ brew tap ArmMbed/homebrew-formulae
$ brew install arm-none-eabi-gcc
μECCライブラリをインストール
- 署名の検証に必要。ARMtoolchainでコンパイルまで実行する。
- おそらくライセンスの関係でバイナリが入っていない?
- ダウンロードし、解答したSDKフォルダの配下、
{SDK folder}/external/micro-ecc
に配置する。 -
{SDK folder}/components/toolchain/gcc/Makefile.posix
のGNU_ROOT
を/usr/local/bin
にかえる
$ cd {SDK folder}/external/micro-ecc/
$ git clone https://github.com/kmackay/micro-ecc.git
$ cd nrf52hf_armgcc/armgcc
$ make
秘密鍵・公開鍵のペアを作る
- 基本的にnrfのsecure DFUは電子署名の仕組みを利用しており、秘密鍵と公開鍵のペアが必要です。秘密鍵で署名しソフトウェアを作成し、Bootloaderには公開鍵を入れておき検証する。
- 参照先にも書いてありますが、あくまで署名なのでOTAする場合、パケットを取ればソフトウェアの中身は取れてしまいます。2
nrfutil keys generate {filename}
でつくれる。
nrfutil keys display --key pk --format code {input_privatekey} --out_file {outputfile_publickey(.c)}
でnrfSDKで利用する形式(hex配列)に公開鍵を出力可能。
$ nrfutil keys generate private.key
$ nrfutil keys display --key pk --format code private.key --out_file dfu_public_key.c
作ったキーを配置する
- 作成したキー(ここではdfu_public_key.c)を下記フォルダに移す
{SDK folder}/examples/dfu/
secure bootloaderのサンプルプロジェクトを開く
-
{SDK folder}/examples/dfu/secure_bootloader/pca10040_ble/ses
にあるプロジェクトをファイルを開く。(segger embedded studioの場合) -
sdk_config.h
のNRF_DFU_HW_VERSION
を任意の数字に変える - Jlinkなどでbootloaderを流し込む
あくまでサンプルプロジェクトなので、必要に応じて中身を変える必要はあるでしょう。
2. アプリケーションに署名をする
bootloaderはとりあえずできたので、次はアプリケーション側の対応を行います。
コンパイルした後のバイナリを探し当てる
Seggerの場合だと、
{project_root}/Output/Releases/Exe
にある、.hex
ファイル。
署名する
$ nrfutil pkg generate --hw-version 1 --application-version 1 --application binary.hex --sd-req 0xA8 --key-file ../private.key output.zip
hw-version
: 先程指定した任意のHWVERSION.一致しないとロードできない。
application-version
: 任意の数字。以前読み込んだバージョンと同等かそれ以上でないとロードできない。
sd-req
: SoftDeviceのバージョン。後述。
key-file
: 先程作った秘密鍵のファイルを指定
sd-req
利用しているSoftDeviceのバージョンを記載する。
nrfutil pkg generate --help
で候補一覧を見れる。
どれが入っているかわからない場合は、アプリケーションで取得することも可能。こんな感じ。
ble_version_t version;
sd_ble_version_get(&version);
NRF_LOG_INFO("SOFTDEVICE VERSION:%x",version.subversion_number);
OTAする
- nrf toolboxもしくは nrfconnectアプリをスマートフォンにダウンロードする。
- できたZIPファイルを何らかの形でスマートフォンへ転送。
- sampleのbootloaderを利用している場合は、"DfuTarg"という名前で表示されるので、よしなにOTAを実行する。
残念なところ
じつはこのままだとDFUした後に再度DFUできないのですが、続きは気が向いたら。
このあたり使います。