モダンOSのお砂場(9) MicroPython、ファイルにアクセス

JosephHalfmoon

前回に引きつづき、M5StickVのMicroPythonのREPL環境で「遊んで」おります。M5StickVの場合、内蔵Flash以外にSDカードも使用できるので、スクリプトやデータの格納場所に困るということはなかなか無さそうです。その分、いろいろファイル操作したくなる局面も多くなると思います。そこで、ちょこっとユーティリティ的なスクリプトを書いて「お手軽化」してみました。

※「モダンOSのお砂場」投稿順Indexはこちら

まずは、M5StickVにmicroSDカードを差し込むところの写真を添付しておきます。M5Stackであるとカード端子面を上にして差し込むことになりますが、M5StickVの場合は、カード端子面下です。

M5Stackの場合は、カードを入れる隙間の遊びが大きめでナナメに入ってしまったことがありました。M5StickVの場合、それほどな遊びはなく(多少ある)、ナナメに入る危険性は少なそうです。ただし、簡単に蓋を開いてソケットむき出し状態にできるM5Stackと違い、M5StickVはネジ止めされています。慎重に差し込んだ方が良さそうです。また、押し込むと内部のバネで外に飛び出してくるM5Stackと違い、手元のM5StickVは押し込んでも外へ出てこないです。しかたが無いので私はラジオペンチでそっとつまんで引き出してます。もともとそんなもんなんだろうか。

さて、micropythonのREPL環境からは、以下のようなファイルシステムがみえていました。

  • /flash
  • /sd

/flashの方が、内蔵のFlashメモリ内の読み書き可能なファイルシステム領域で、/sdの方が、側面のmicroSDカードです。ディレクトリ内のファイルのリストを調べる場合、uosまたはosモジュールを使い、

uos.listdir(‘/sd’)

てな具合でファイル名がリストされます。

MicroPythonの場合、公式ドキュメントを読むと、モジュール名 uos の筈なのですが、M5StickV上のMaixPy環境ではPython同様のモジュール名 os という名でも使用可能です。実体は同一のモジュールであるようです。ここではご本家に則り uos という名で呼び出します。

上記の方法でリストすると、返って来るのはファイル名のリストです。プログラムで処理する場合は都合が良いですが、REPLの上でインタラクティブにリストする場合、読みずらい。それだけでなく、ファイルなんだかディレクトリなんだか識別できないし、ファイルサイズも分からない。そこでインタラクティブ呼び出し用の小さな関数を作成しました。(ucmdと名付けたclassの中のクラスメソッドとして)

    @classmethod
    def dir(cls, pth):
        for item in uos.ilistdir(pth):
            if len(item) < 2:
                print(str(item))
            if (item[1] & 0x8000) != 0:
                print("F ",item[0],item[3])
            elif (item[1] & 0x4000) != 0:
                print("D ",item[0])
            else:
                print(str(item))

上記の関数で /sd を調べればこんな感じ

F  a.txt 102
F  b.txt 4
D  System Volume Information

先頭にファイルならF、ディレクトリならDと記され、ファイル名の後にファイルサイズ(バイト)が続きます。なお、最後の”System Volume Information”というディレクトリが気になったので内部を覗いてみると以下のように2つのデータファイルが含まれているように見えていました。

>>> ucmd.dir('/sd/System Volume Information')
F  WPSettings.dat 12
F  IndexerVolumeGuid 76

pythonのスクリプトを実行するとき、このM5StickV環境では/flash直下のスクリプトをインポートして走らせることができます。

import hogehoge

でも、インポートせずに単独のスクリプトとして走らせるならば、

>>> exec(open(’path’).read())

てな具合。かなり書くのが面倒。そこでこれも関数にしてしまいます。

    @classmethod
    def run(cls, pth):
        exec(open(pth).read())

さらに、ファイルの内容をtype(linuxならばcat)もしたい。

    @classmethod
    def type(cls, pth):
        with open(pth) as f:
            for lin in f:
                print(lin,end='')

それにつけても、いちいち、ucmd.dir(’ほげほげ’)などと書くのはまどろっこしい、ということで、結局、Windowsのcmd.exe風のマイクロなコマンドインタプリタも用意してしまいました。

    @classmethod
    def cmd(cls):
        flag = True
        while (flag):
            print("$ ",end='')
            lin = input()
            linL = lin.split()
            if len(linL) < 1:
                continue
            elif len(linL) == 1:
                linL.append(uos.getcwd())
            try:
                if   linL[0].startswith('exit'):
                    flag = False
                elif linL[0].startswith('d'):
                    cls.dir(linL[1])
                elif linL[0].startswith('t'):
                    cls.type(linL[1])
                elif linL[0].startswith('r'):
                    cls.run(linL[1])
                elif linL[0].startswith('e'):
                    cls.edit(linL[1])
            except:
                print("ERROR: ", str(linL))

一たび ucmd.cmd() を実行すればこんな感じ。

$ dir /flash
F  ding.wav 158804
F  startup.jpg 27867
F  freq.conf 12
F  boot.py 3519
F  hello.py 80
F  ucmd.py 1481
$ type /flash/hello.py
import lcd

lcd.init()
lcd.draw_string(0,0, "hello world", lcd.BLUE, lcd.BLACK)
print("TO CONSOLE: Hello World!")
$ run /flash/hello.py
TO CONSOLE: Hello World!
$ exit
>>>

限りなく「モダンじゃない」感じですが、やりたいことはできると。

モダンOSのお砂場(8) M5StickV、MicroPython へ戻る

モダンOSのお砂場(10) MicroPython、モジュールとhelp へ進む