Raspberry Pi PicoのMicroPythonでdupterm()を使う


ラズピコのMicroPythonで、以前作成したST7735ドライバFBConsoleの動作テストをしてみました。ST7735ドライバは広く使われているTFT LCDモジュールのコントローラチップのドライバ、FBConsoleは任意のFrameBuffer互換のデバイスをREPLの出力先として利用できるようにするクラスです。
結果、両方ともコード自体は変更の必要なく動作するのですが、FBConsoleについてはこれを利用するためのdupterm()が動きません。
【2023/5/17追記】現在のMicroPython v1.20.0 (2023-04-26) .uf2 はdupterm()をサポートしています。

この機能は、

uos.dupterm(object)

とすると、objectに対してREPLの入出力が行われるようになるものです。objectは文字列描画やスクロール、REPLで使われれるエスケープシーケンス等を処理できる必要があります。簡単に言うと、objectを実装するのは簡易的なターミナルエミュレータを実装するようなものです。FBConsoleは、FrameBufferクラスの文字描画機能等を使ってこれを実装しています。

今回は、そもそもdupterm()が動作しませんでした。調べてみたところ、

・PicoのMicroPythonは、デフォルトではdupterm()は無効になっている
・dupterm()を有効にしても、REPLのデータをdupterm()で指定されたデバイスに送ってくれない

という2つの原因がありました。

前者については、uosモジュールの中でdupterm()メソッドが
#if MICROPY_PY_OS_DUPTERM
#endif

で囲われており、かつMICROPY_PY_OS_DUPTERMは偽になっています。

MICROPY_PY_OS_DUPTERMの値を設定するには、CMakeLists.txtのtarget_compile_options

-DMICROPY_PY_OS_DUPTERM=1

を追加することで有効化できます。あるいは、

env CFLAGS="-DMICROPY_PY_OS_DUPTERM=1" cmake . -B build

のようにすると、環境変数経由で無理やり設定することができます。

後者については、そもそも実装されていなかったので、コードの修正が必要でした。

mphalport.cの中で定義されている、REPLの文字列出力を行う関数mp_hal_stdout_tx_strn()の中で、REPLの出力文字列をdupterm()で指定されたオブジェクト(上の図のdupterm_objs)にも送る必要があります。そのための関数はmp_uos_dupterm_tx_strn()です。(以前、こちらの記事で少し触れていました。)

今回この部分が実装されていなかったので、mp_uos_dupterm_tx_strn()の呼び出しをmp_hal_stdout_tx_strn()に追加することで、FBConsoleが動作するようになりました。
ごく僅かな修正ではありますが、プルリクエストを投げてあります。

rp2/mphalport.c: Add dupterm TX support. by boochow · Pull Request #6940 · micropython/micropython
This PR adds mp_uos_dupterm_tx_strn() call into mp_hal_stdout_tx_strn() to make uos.dupterm() work. Also I added #includ...

もっとも、Picoで推奨されるIDEであるThonnyはdupterm()向きではありません。ThonnyはREPLではなくraw REPLを使用し、人間には見せない形でMicroPython処理系とデータをやりとりしています。dupterm()を使うと、その生のデータがduptermデバイスに送られてしまいますので、Thonnyを使っている環境でduptermを使うとユーザは混乱するかもしれません。

I2C接続のSSD1306にREPLを出力する場合のコードと接続の例は、こんな感じになります。

また、SPI接続のST7735 LCDにREPLを出力する場合のコードと接続の例は、こんな感じになります。


なお

'ST7735.py', 'ST7735fb.py', 'fbconsole.py', 'petme128.py', 'ssd1306.py'

の各ファイルは、あらかじめMicroPython側のファイルシステムに転送してある想定です。(またはCtrl-E/Ctrl-DによるPaste Modeを使って直接読み込ませておいても良いです。)ファイルの転送はThonnyが使えますが、duptermの実験自体には前述のようにThonnyはあまり向いていませんので、TeraTermなどの通信ソフトを使用してください。

duptermから抜けるには
uos.dupterm(None)
です。

コメント