SoftDevice ファームウェア
Bluetooth プログラムを実行する前に、SoftDevice と呼ばれる特別なファームウェアを micro:bit に書き込む必要があります。このファームウェアは、micro:bit v2 で使われている nRF52833 チップのメーカーである Nordic Semiconductor によって提供されています。
このチップでは、メモリ効率のよい Bluetooth Low Energy (BLE) プロトコルスタックである SoftDevice S113 を使用します。これはペリフェラルとして最大 4 つの同時 BLE 接続をサポートし、データをブロードキャストすることもできます。
ダウンロード
-
Nordic Semi のダウンロードページにアクセスします: https://www.nordicsemi.com/Products/Development-software/S113/Download
-
パッケージをダウンロードします。私の場合は、DeviceDownload.zip という名前のファイルを取得しました。
-
DeviceDownload.zip を展開すると、s113_nrf52_7.3.0.zip という別のファイルがあります。
-
その zip も展開してください。中には、次のような内容があります:
.
├── s113_nrf52_7.3.0_API
├── s113_nrf52_7.3.0_license-agreement.txt
├── s113_nrf52_7.3.0_release-notes.pdf
└── s113_nrf52_7.3.0_softdevice.hex
1 directory, 3 files
目的は .hex ファイルです。これは、バイナリのファームウェアデータを読みやすいテキスト形式で格納する特別なファイル形式(Intel HEX)です。
SoftDevice をフラッシュする
micro:bit にファームウェアを書き込むには、次のコマンドを実行します:
probe-rs download s113_nrf52_7.3.0_softdevice.hex --binary-format Hex --chip nRF52833_xxAA
他の演習で SoftDevice ファームウェアが上書きされている可能性があるため、BLE の演習に戻ってくるたびにこの手順をやり直す必要がある点に注意してください。
memory.x ファイルを更新する
SoftDevice を書き込んだら、Rust プログラムが SoftDevice の使用するメモリ領域を上書きしないようにする必要があります。
そのために、memory.x リンカスクリプトを更新します。このファイルは、Rust コンパイラがアプリケーションで使用できるメモリ領域を定義します。
元の memory.x ファイル
MEMORY
{
FLASH : ORIGIN = 0x00000000, LENGTH = 512K
RAM : ORIGIN = 0x20000000, LENGTH = 128K
}
更新後の memory.x ファイル
MEMORY
{
/* 注 1 K = 1 KiBi = 1024 バイト */
MBR : ORIGIN = 0x00000000, LENGTH = 4K
SOFTDEVICE : ORIGIN = 0x00001000, LENGTH = 112K
FLASH : ORIGIN = 0x0001C000, LENGTH = 396K
RAM : ORIGIN = 0x20003410, LENGTH = 117744
}
これによりリンカは、SoftDevice に予約されたフラッシュおよび RAM 領域の後ろからプログラムを開始するため、実行時のメモリ競合を防げます。
これらの値はどこから来るのか?
これらの値は、hex ファイルと一緒に提供される PDF ドキュメント(s113_nrf52_7.3.0_release-notes.pdf)に基づいています:
フラッシュメモリ
SoftDevice は、0x00001000 から始まる先頭 112 KB (0x1C000) のフラッシュメモリを使用します。つまり、アプリは 0x0001C000 より後ろから開始する必要があり、使用可能なフラッシュは 512 KB - 112 KB - 4 KB (MBR) = 396 KB になります。
RAM の計算
SoftDevice が必要とする最小 RAM 量は、どのように設定するかによって変わります。リリースノートによると、少なくとも 4.4 KB (0x1198) が必要で、さらにコールスタック用として約 1.8 KB (0x700) を使用する可能性があります(最悪の場合)。しかし実際には、予約すべき正確な量を推測したり手計算したりする必要はありません。
便利なのは、プログラム実行時に nrf-softdevice crate が必要な RAM 量を正確に教えてくれることです。
コツは次のとおりです。まずは小さめに RAM を予約します。たとえば、プログラムの RAM 開始アドレスを 0x20001fa8 に設定してみてください(つまり、最初は約 8 KB を予約することになります)。プログラムを書き込んで実行すると、次のようなログが表示されます:
softdevice RAM: 13328 bytes
この場合、必要なのは 13328 バイトで、16 進数では 0x3410 です。これが、最終的な memory.x でプログラムの RAM 開始位置を 0x20003410 に設定している理由です。チップ上の総 RAM は 128 KB = 131072 バイトなので、アプリで使える残りの RAM は次のようになります:
# remaining_ram = total_ram - softdevice_ram
remaining_ram = 131072 - 13328 = 117744 bytes
これが、SoftDevice が必要分を確保したあとにプログラムが使える RAM です。
SoftDevice の RAM 計算を理解するにあたって助けてくれた Dario Nieuwenhuis に特別な感謝を伝えます。
注: 後で SoftDevice の設定が変わった場合は、memory.x 内の RAM の開始位置と長さを調整する必要があるかもしれません。ただし心配はいりません。nrf-softdevice crate が実行時に必要な RAM 量を正確に教えてくれます。その値に合わせて調整し、プログラムを再実行できます。
RAM : ORIGIN = 0x20003410, LENGTH = 117744
また、SoftDevice に必要以上のメモリを割り当てると、nrf-softdevice crate が警告してくれます。