ベアメタル版MicroPythonのRaspberry Pi2対応:なんとか動作

先日着手した、ベアメタル版MicroPythonのRaspberry Pi2対応ですが、その後いくつかバグをつぶして何とか動作するようになりました。

以下、主に自分用のメモです。

・全般

Pi 2ではI/Oアドレスが0x3f000000からになります(Pi 1は0x20000000)。
そのため、CSUDも含めて書き換えを行いました。

CPUも異なるので、コンパイルオプション

-mcpu=arm1176jzf-s

-mcpu=cortex-a7

に書き換えます。

FPU関連のオプションは

-mhard-float -mfpu=neon

を指定しました。
-mhard-floatは-mfpu=… とセットで使用することが必須です。これを指定していないと、libgccが適切に選択されず、リンクエラーになります。
hard-floatではなくsoftfpを使うという選択肢もあります。

何を指定するにせよ、実行ファイル全体で同じコンパイルオプションを用いる必要があります。
CSUDにも同じオプションを指定しなければなりませんので、CSUDのmakefileを変更して外部からコンパイルオプションを指定できるようにしました。

FPU関連は下記が参考になりました。

Demystifying ARM Floating Point Compiler Options — Embedded Artistry

・CSUD(USBライブラリ)

以前、Pi ZeroにオンボードのUSB Hubが無いため、root hub(チップのUSB I/Fそのもの)に直接デバイスを抜き差しした場合の処理を追加しました
今回はPi2なので、オンボードUSB Hubが載っています。
オンボードのUSB Hubに上記の処理が適用されると動作がおかしくなるバグが見つかり、Root Hubに対してのみ処理が適用されるように条件分岐を追加しました。

また、DMAバッファがキャッシュ領域上にあるとデータの変更が読み取れない場合があるので、バッファのアドレスを0xC0000000でORして非キャッシュ領域のアドレスに変換して利用します。

USBポートの状態変化検出はgetcの中で行っていますが、そのためUSBキーボードを最初に検出できるのは、MicroPythonの起動後にREPLのプロンプトが表示された後になります。
結果、キーボードが検出されたメッセージががREPLのプロンプトの後に出力されてしまいます。
見栄えが悪いので、USBの初期化の後、100msecごとに5回、USBポートをチェックしてキーボードがあればREPLを表示するよりも前に検出できるようにしました。

・SD Card

一部の変数を64bitにしていましたが、32bitにすべきだったので修正しました。

・その他

GPUから返されるフレームバッファのアドレスが、非キャッシュ領域のアドレスとなっており、これをそのまま使うと読み書きできないのでフィジカルアドレスに変換(0x3fffffffとANDを取る)する必要がありました。

Pi 2ではCPUモードにHYP(ハイパバイザ)モードが増え、起動直後は(start.elfによって)HYPモードになっています。

RPi 2 boots in HYP mode (bare metal) – Raspberry Pi Forums

Pi 1のMicroPythonはスーパーバイザモードで動作していますので、互換性を保つため起動直後にスーパーバイザモードに切り替えています。
ハイパバイザモードのままだと起動途中で止まってしまいます。ちゃんと調べていませんが、割り込み関連などで動作が異なるのかもしれません。

コメント