前回、あれこれと考えたMicroPythonへのUSBキーボード接続ですが、とりあえず簡単にできそうなREPL専用の実装をやってみることにしました。
基本的には、REPLのためにシリアルポートから1文字ずつ読む関数mp_hal_stdin_rx_chr()が、USBキーボードで入力された文字を返せればOKです。
その前にまず、csudライブラリがMicroPythonの上で動作するよう環境を整える必要があります。
csudライブラリはビルドオプションとしてSTANDALONE、LOWLEVEL、DRIVERの3つが用意されています。
今回はメモリ管理をMicroPython側で行いますので、DRIVERでビルドします。
csudをDRIVERとして動作させる場合は、include/platform/platform.hで定義されている関数を環境側で用意しなければなりません。
MicroPythonにはハードウェアを抽象化するレイヤ(mphal)がありますので、その中から適切な関数を選ぶことになります。
注意が必要なのはメモリの確保とGCです。
MicroPythonのドキュメントには、メモリ確保にはpy/misc.hで定義されている「m_new, m_renew, m_del (and friends)」を使え、と書かれていますが、これで確保したメモリはGCの対象になります。
GCでクリアされないためには、確保したメモリブロックがMicroPythonのrootポインタから辿れる必要があります。
このあたりのことはフォーラムの以下のスレッドで書かれていました。
help is appreciated – memory allocated by m_malloc() is automatically free'ed – MicroPython Forum
お作法としては
・GCからメモリを保護したいポインタは、普通に変数を宣言するのではなく、mpconfigport.hの中のMICROPY_PORT_ROOT_POINTERSへ変数の宣言を追加する。
・保護したいポインタを参照する場合、常にMP_STATE_PORT()マクロで囲う。
となります。
csudの変数でstaticになっていてAllocateMemory()でメモリを確保しているものは、「Core、Host、Power、Devices」の4つのようなので、これらの変数へのポインタからなる構造体を定義し、それをroot pointersへ追加しました。
他に、USBキーコードから文字コードへの変換の処理も必要になります。
今回はとりあえず、キー配列はUSキーボードに決め打ちでテーブルを参照するようにしました。
これで、どうやらUSBキーボードから入力できるMicroPythonができました。
(まだ安定しておらず、放置しているとハングアップしてしまいますが・・・)
コメント