Moiz's journal

プログラミングやFPGAなどの技術系の趣味に関するブログです

Raspberry Piのベアメタル環境からSDCARDにアクセスする(BUSモード編)

はじめに

Raspberry Piのベアメタル環境からGPIOを経由してSD CARDをアクセスする方法について、BUSモードでも成功したので紹介します

BUSモード

前回のエントリーではRaspberry PiでOSなどを介さず、EMMC 1も使わず、GPIO機能のみを使ってSD CARDにSPIモードでアクセスする方法を紹介しました。 しかし、SPIモードの使用には

  1. 一旦BUSモードで動作すると、SPIモードには再遷移できない
  2. Raspberry PiブートローダーはSD CARDにBUSモードでアクセスる
  3. したがって、デモでSPIモードを使用する前にユーザーがカードを一度抜き差しして、カードをリセットする必要がある

という問題がありました。 また、SD CARDの規格としても、SPIモードはあくまで簡易的にデータにアクセスするための方法です。したがってできることならBUSモードでSD CARDにアクセスしたいと思っていました。

例えば、SPIモードの特徴は以下のとおりです

  1. 使用するピンが少ない。電源とグラウンドを除くと、クロック1ビット、コマンド1ビットとデータ1ビットの、3本の信号線のみ2
  2. 制御が比較的簡単
  3. ただしデータが1ビットしかないので遅い

それに対してBUSモードは

  1. 最大4ビットのデータ線が使える
  2. SD CARDの最近の高速モードに対応している
  3. したがって速い
  4. ただし、制御はSPIモードに比べて若干面倒

となります3。 このように、BUSモードこそがSD CARD本来のモードと言えると思います。

今回は高速化を期待してBUSモードに対応させてみました。

リポジトリと使用方法

今回のデモの内容はGithubで公開してあります。

github.com

使用方法は

  1. 必要ないSD CARDを用意する4
  2. SD CARDにラズビアンOSなどをインストールしてRaspberry Piが起動するようにしておく
  3. SD CARDのboot領域のkernel.imgをリポジトリのkernel.imgで置き換える
  4. SD CARDをRaspberry Piに挿して起動する

なお、デモの結果を確認するにはSerialのTX/RXをRaspberry PiのGPIO#14/15(PIN8とPIN10)に接続し、PCなどのターミナルコンソールに信号の内容を表示させる必要があります。

デモの出力結果は以下のようになります。SD CARDのFAT32領域にアクセスして、ルートディレクトリのファイルを表示しています f:id:uzusayuu:20180730070201p:plain

前回との違い

SPIモードとBUSモードの違いは上記のようにいろいろありますが、今回影響を強く受けたのは以下のような点です

  1. コマンド(CMD)が双方向になった。SPIモードではCMDはホストからカードへの一方通行だったのですが、BUSモードではカードからホストにレスポンスを返すのにも使います
  2. データビットが1ビットから4ビットに増えた。BUSモードでは4本あるデータ線をすべて使うことができます
  3. コマンドやレスポンスのフォーマットがSPIモードと違う。

とくに、コマンドに対するレスポンスがデータと同時に帰ってくることがあるため、両者を同時に処理する必要がある点に注意が必要です。

なお、今回は読み込みまでしか実装していません。

実装の詳細についてはgithubで公開しているソースコードを参照ください5

次への課題

この実験は、もともとは、既存のライブラリで動作していた「Haribote OS」のSD CARD読み込み部分を、自分の実装で置き換えるというのが目的でした。これからそのあたりやっていこうと思っていたのですが、一時帰国で日本に帰った際にこんな本を見つけてしまいました。FatFSという組み込み向けFATライブラリーの解説本です。

shop.cqpub.co.jp

Haribote OSではFATの扱いはごく簡単なもので、残りの実装は読者への宿題になっています。こちらの本で解説されているFatFSを使えば読み書きやディレクトリのアクセスも含めたファイルシステムをサポートすることができそうです。ちょっと気になってきました。

まとめ

Raspberry Piのベアメタル環境でGPIOを経由してSD CARDをアクセスするデモについて紹介しました。 なお今回はリードのみの実装です。また、UHSなどの高速化モードはいっさいサポートしていません。


  1. Raspberry PiのSoC(BCM2835)のSD CARDインターフェース機能

  2. 規格としてはCS(チップセレクト)信号もあるが、Raspberry PiではSD CARDは一つしか繋がらないのでCSは必要ない

  3. 詳しいことはSD Associationが発行している簡易版規格書のパート1をご覧ください。

  4. デモでSD CARDの内容が破壊される可能性もありますので、必ず必要ないSD CARDを使用してください

  5. うまくまとまったらブログに書くことも考えています