前回は「絶対番地アクセス可能なヤバイ奴」uctypesモジュールと structモジュールが「相互運用可能」ということで便利だと喜びました。「絶対番地」でアクセスできるので当たり前っちゃ当たりまえです。今回は、arrayモジュールの配列もまたuctypesでアクセスできるというこれまた当たり前の件を実習してみます。
※「MicroPython的午睡」投稿順 Indexはこちら
メモリ容量の限られたマイクロコントローラ(マイコン)上のMicroPythonなので、数値配列をガッツリ確保するarrayモジュールについては「メモリ容量とご相談の上ご使用ください」ということで、大分前にちょっと調べてみたことがありました。その時の記事が以下に。
MicroPython的午睡(42) array.array、意外に小さい使える領域
また、MicroPythonのarrayモジュールの日本語ドキュメントは以下にあります。
arrayモジュールと呼んでいますが、手元のラズパイPico用のMicroPython v1.15を見れば、正確にはuarrayモジュール内のarrayクラスというべきでしょう。モジュール一覧が以下に。uarrayモジュールが見えてます。
import uarrayして uarrayの中身を調べてみると、こんな感じ。
ご本家Pythonの array には多数のメソッドがあるものの uarray.arrayには3つのみ。まあ数値配列定義して使えるということで十分か。
実験に使用したソース全文
以下のソースでは、符号無バイト型(”B”)の8要素、初期値0([0]*8)の配列を定義し、その全体を標準出力に表示後、一部要素に書き込み、再び全体表示、そして最後に STRUCT1 型の「構造体」を uctypes をつかってこの配列の上に「重ねて」一部の要素を32ビット符号無整数として読み取ってます。言葉で書くよりソースの方が簡単明瞭。
import uctypes, uarray STRUCT1 = { "field0" : 0 | uctypes.UINT32, "field1" : 4 | uctypes.UINT32, } def main(): ubArray = uarray.array("B", [0] * 8) print(ubArray) ubArray[1] = 0x30 ubArray[2] = 0x31 ubArray[3] = 0x32 print(ubArray) adr0 = uctypes.addressof(ubArray) sct1 = uctypes.struct(adr0, STRUCT1) print("STRUCT1.field0 : 0x{0:08x}".format(sct1.field0)) if __name__ == "__main__": main()
当然ながら単なるバイト型の配列は、単なるメモリと同義、何の問題もなく uctypesでも扱えます。勿論バイト型でなくても配列はベタなデータの並びなのでOKっすけど。
バイナリは安心。uctypesあれば、何でもできるような気がしてくるから不思議。