SDカードへの書き込み(RPiベアメタルMicroPython)

ベアメタルRaspberry Pi版MicroPythonでは、SDカードについては、読み込み機能のみを半年ほど前に実装していました。

SDカードを読む(RPiベアメタルMicroPython) – 楽しくやろう。

書き込み機能をつけなかったのは、利用させていただいたライブラリに書き込み機能が無かったことが大きな理由です。

その後、書き込み機能のほうはさぼったままだったのですが、1ヶ月ほど前にMicroPythonのフォーラムで、OLEDのドライバなど様々に活躍されているPeter(pythoncoder)さんに、RPi版MicroPythonについて

SDカードに書き込みできない点が問題だと思うよ。コードをアップデートするたびにPCでSDカードに書かないといけないのでは? rshell経由でアップデートできるなら、Pi Zeroを手に入れて試してみたくなるけど(^_-)

キーボードとか、イーサネットとかWiFiとかのサポートは飾りに過ぎないよ。

The main issue I can see is the inability to write to the SD card. Does this mean writing the SD card on a PC each time you want to update your code? If rshell could do updates I’d find it hard to resist getting a Pi Zero to try it out 😉

Support for keyboard, Ethernet and WiFi would be the icing on the cake

言われてしまいました

なので「今取り組んでいるPWM関係が片付いたら、書き込み機能を追加しますね」と答えたのですが、今回ようやく着手しました。

以前読み込み機能の記事でも書きましたが、今出回っているRaspberry PiのベアメタルでのSDカードドライバは、概ね以下のスレッドに端を発しています。

[BARE-METAL][SDC/EMMC] How to access it properly?? – Raspberry Pi Forums

このスレッドに、まずhldswrthさんがほぼ完成されたドライバを投稿されました。
このドライバは書き込み機能がありました(transferblocksという関数で、バッファからSDカードへ/SDカードからバッファへ のどちらもサポートしています)。

それ以降のドライバはhldswrthさんのコードから派生しており、

・バグ修正を含んだ、moizumi99さんのHaribote-OS版
・ドライバコードを整理し、FATの実装(現状、読み出しのみ)を追加したLdBさんの版

はどちらも書き込み機能があります。

一方、私が使用したbztsrcさんの版は、上記のドライバをベースに、機能を読み出しのみに絞ったほか、Raspberry Pi3で動かすことを前提に、クロックの設定などいくつかの処理を簡略化しています。

ですが、大元のドライバは上記のhldswrthさんの版で、ロジック自体もほぼ変化が無いので、両方のコードを見比べていけば書き込み機能を付け加えるのはそれほど難しくはありません。

実際のところ、読み出し処理と書き込み処理の主な差分は、コントローラへのコマンド(readかwriteか)、チェックする割り込みフラグの条件(readかwriteか)、データを読み出す(変数=レジスタ)か書き込む(レジスタ=変数)か、および書き込み終了後に書き込み完了チェックをすること、の4点に過ぎません。

ただ、ロジックではなく、タイミングの部分で動作が安定するまでに若干苦労しました。

SDカードクラスにブロック書き込み機能を追加した後、以下のようなコードで書き込みをチェックしました。

すると、どうもうまく動作しません。
ファイルを作成することはできるがファイルに書けない、という微妙な症状でした。

そこで、ファイルシステムを介さずにセクタを直接読み書きするコード(SD.writeblocks(addr, buf)を使います)を作って試してみましたが、やはりうまくいきません。

デバッグメッセージをONにしていると動作するのに、OFFにすると失敗するという現象が起こります。
ちなみに、セクタを読み出して表示するのは以下のようなコードです。(この例では0xbb00というアドレスのセクタを表示させています。)

どうも、書き込めたり失敗したりはタイミング的なものがあるようなので、いろいろと実験してみて、結局SDカードコントローラのクロックを下げて(20MHz→10MHz)みたところ、どうやら安定して動作するようになりました。

このあたりはSDカードの違いにも依存する可能性がありますし、SDHCカード以外でのテストもしていないので、安心して使える状態ではないかもしれませんが、現状ではfile.write(str)で44KBくらい書いて問題なく書き込めています。

コメント