LoginSignup
6
9

More than 3 years have passed since last update.

nrf52でOTAする(Secure Bootloader+DFU)

Last updated at Posted at 2019-05-16

前提

  • nrf5Xの開発を行っている
  • OTAをしたい(Bluetooth経由でアプリケーションをアップデートしたい)
  • Segger Embedded Studioを使う
  • OSXで開発

公式ガイド

ここみれば一応解決はします。

背景

  • nrf52で開発しているとやはりFirmware OTA(Over-the-air)はしたい。
  • そもそもOTAで見ず知らずのアプリケーションを書き込めるのは嫌だ
  • SDK12以降はsecureじゃないDFUはできない1

やること

  1. secure bootloaderを書き込む
  2. アプリケーションに署名をする

1.secure bootloaderを書き込む

事前準備もろもろ必要なもののインストール

ひつようなもの

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.posixGNU_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.hNRF_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する

残念なところ

じつはこのままだとDFUした後に再度DFUできないのですが、続きは気が向いたら。
このあたり使います。

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9