Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

まだですか?

プログラムのビルドには成功しましたが、もうこれをフラッシュして(micro:bit の永続メモリに書き込み、実行して)よいのでしょうか? まだですが、かなり近づいています。その前に、あといくつか完了しなければならない手順があります。

cargo embed を実行してみると、次のエラーが表示されます。

...other warnings...
WARN probe_rs::flashing::loader: No loadable segments were found in the ELF file.
Error No loadable segments were found in the ELF file.

このエラーは、コンパイラが作成したファイル(ELF ファイル)に、フラッシャーが micro:bit に書き込むべき実際のコードやデータが含まれていないことを意味します。言い換えると、そのファイルはフラッシャーの視点では空です。

なぜこうなったのでしょうか? それは、コンパイラがプログラムをメモリ上のどこに配置すればよいかを知らないためです。cortex-m-rt crate を使っているとはいえ(これによりスタートアップコードやその他のサポートが提供されます)、リンカーは依然として micro:bit のメモリレイアウトを把握する必要があります。この情報がないと、実際のプログラムを出力ファイルに配置する処理をスキップしてしまいます。

エラーの修正

これを解決するには、link.x という特別なスクリプトを使うようコンパイラに伝える必要があります。このスクリプトは cortex-m-rt crate によって提供され、コードやデータをメモリ上にどのように配置するかをコンパイラに伝えます。

.cargo/config.toml を次のように更新してください。

[target.thumbv7em-none-eabihf]
rustflags = ["-C", "link-arg=-Tlink.x"]

この行は、コンパイラに「メモリレイアウトを決定するために link.x を使ってください」と伝えるフラグを追加しています。

memory.x

cortex-m-rt crate のドキュメントによると、マイクロコントローラのメモリレイアウトを定義するために memory.x というファイルが必要です。このファイルは、フラッシュと RAM がどこから始まり、どれくらいの大きさなのかをリンカーに伝えます。

では……それはどこにあるのでしょうか?

この時点で実際にデバイスへフラッシュしてみると、プログラムは micro:bit に書き込まれて実行されるはずです。これは、memory.x ファイルが nrf52833-hal crate から自動的に取り込まれるためです。ここで確認できます: https://github.com/nrf-rs/nrf-hal/blob/master/nrf52833-hal/memory.x

ただし、曖昧さを避けるためには、自分たちのプロジェクト内で memory.x ファイルを定義しておくほうが望ましいです。そこで、プロジェクトのルートフォルダに memory.x という名前のファイルを作成し、次の内容を記述してください。

MEMORY
{
  FLASH : ORIGIN = 0x00000000, LENGTH = 512K
  RAM : ORIGIN = 0x20000000, LENGTH = 128K
}

これは、フラッシュと RAM がどこから始まり、どれだけのメモリが利用可能かをリンカーに伝えます。

  • ORIGIN = 0x00000000 は、フラッシュメモリがアドレス 0x00000000 から始まることを意味します。
  • LENGTH = 512K は、フラッシュメモリのサイズが 512 キロバイト(512 × 1024 バイト)であることを意味します。
  • ORIGIN = 0x20000000 は、RAM がアドレス 0x20000000 から始まることを意味します。
  • LENGTH = 128K は、RAM のサイズが 128 キロバイトであることを意味します。

これらのアドレスとサイズは、nRF52833 のドキュメントに基づいています。


この時点で、プロジェクトフォルダは次のようになっているはずです。

├── .cargo
│   └── config.toml
├── Cargo.toml
├── memory.x
└── src
    └── main.rs

フラッシュする

それでは、プログラムをビルドしてフラッシュしてみましょう。

cargo flash

# OR

cargo embed

今回は、ELF ファイルに有効なロード可能セグメントが含まれるため、フラッシャーはそれを micro:bit のフラッシュメモリに書き込めるようになります。

すべてうまくいけば、プログラムは micro:bit 上で実行されているはずです。最初の LED が点滅しているのが見えるでしょう。

参考資料