巨大なプログラムをmicroPythonで動かす。
投稿日: May 12, 2019 1:51:3 PM
これは2つの問題と戦う内容です。
一つはメモリ、もう一つはストレージ。
まずメモリの問題。
テキストで書かれたスクリプトを読み込むのです。メモリは当然かなり消費します。
コメントとかが死ぬほど書かれたスクリプトならコンピュータにとって全く意味のないコメントのためにメモリを大量消費する可能性もある。かもしれない。(流石に回避してると思うけど)
コメントはさておいたとしてもどっちにせよメモリの大きさに対して文字数で動かせるプログラムサイズは決まってくるみたいなとこがあります。JITコンパイラみたいな素敵な技術はまだembeddedなPythonには来ていないんです。
で、予め中間コードのバイナリにコンパイルしておくための仕組みがあります。それが mpy。
mpy-crossコンパイラでスクリプトをmpyバイナリに変換できる。
mpyの利用は通常通りimportでモジュール読み込みしてやればそのまま動く。
micro:bit以外の環境ではこの手段を用いることでちょっと大きめのスクリプトが動かせます。
もっと大きなスクリプトを動かしたいとか、micro:bitにも愛の手を。みたいな話になると。
Javaなんかでよくやってる動的ロードを思いつきます。
やり方はかんたん。プログラムの部品をモジュールとしてimportで順次読み込んで実行してゆけばよいわけです。
動作させた後はメモリから追い出すのを忘れちゃだめ。microPythonでは一部機能にガベージコレクションが働かないのでモジュールの中でグローバル定義したような配列とかは確実にメモリに居座るのでしっかりお掃除する。
del命令やsys.modules.popなどを利用する。
ココらへんは別サイトで解説しているのでここでは割愛。
で、いつの間にか問題はストレージへとずるずる変わってゆきます。
パソコンよくわかってない人はメモリとストレージの違いがわかってないみたいな、そんな話もアリますが完全にわけられる問題ではないわけで詳しくなかったら混同してもおかしくないよねとか。
ストレージに関して ATSAMD21G18(M0)のPSRAMなしとかmicro:bitとかだとSDカードを扱うというのはかなり大変。micor:bitに至っては機能が実装されてないのでそもそも無理。
大きなプログラムを動かすつもりがあるならM0 Express、M4 ExpressとかpyBoardとかESP32とかを選ぶべきなんですが、それでも。どうしてもmicro:bitで大きなプログラムを動かしたいとしましょう。
つまりそういう話です。
ここまで前置きです。ながい前置きでした。
方法としては2つほどあります。
一つは何らかの通信手段で別のMCUと接続してそちらのMCUでストレージを管理してもらう方法。
もう一つはmicro:bitにでもアクセス可能な何らかのメディアに読み書きする方法。
前者はどうとでも出来る内容だけどコストが大きいのでここでは可能性の一つとして挙げることのみで触れるのはやめておきます。
後者、こちらですね。
EEPROMなどはお手軽にそこそこの容量を手に入れることが出来ます。
通信速度はアレですけどI2Cで出来ますしネ。
どのようにデータを扱うかという点については色々考えては居ますがまさかEEPROM上にファイルシステムを作ってどうのこうのなんてのはあんまり考えたくないのでEEPROMのストレージ容量をある程度の大きさでページとして管理してページごとに読み書きするような感じにすれば理解はしやすいだろうし。実際メモリに読み込めるスクリプトサイズなんてそんな巨大なものは無理ですし。十分そうです。
実行の仕方はEEPROMからbufという変数にデータをすでに読み込んだという前提で。
exec( buf )
これだけです。
あらかんたん。
しかしEEPROMにスクリプトを書き込むとかいうその方法を考えるのが大変そうですが。
micro:bit以外のmicroPythonボードで。SDカードとか何らかのストレージ領域を使ってやるなら。
f = open("スクリプトファイル名.py" , "r" )
buf = f.read()
f.close()
exec( buf )
こんな感じで可能。
evalは式を評価するものでexecは関数を評価する。という説明であってるんだろうか。
スクリプトを動かすならexecです。
ということでストレージさえどうにかなればどうにかどんな大きなプログラムでも動かせそうな気がするでしょう?
いずれこのあたりはmicro:bitとかで実際に試してみたいと思ってます。