uos
-- 基本的な「オペレーティングシステム」サービス¶
このモジュールは、該当する `CPython` モジュールのサブセットを実装しています。
詳しくはオリジナルの CPython ドキュメンテーションを参照してください: os
.
uos
モジュールには、ファイルシステムのアクセス、マウント、ターミナルのリダイレクトと複製、uname
と urandom
のための関数があります。
一般関数¶
-
uos.
uname
()¶ 基盤のマシンやオペレーティングシステムに関する情報を含むタプル(おそらく名前付きタプル)を返します。タプルには次の5つのフィールドがあり、それぞれが文字列です。
sysname
-- 基盤システムの名前nodename
-- ネットワーク名(sysname
と同じこともあります)release
-- 基盤システムのバージョンversion
-- MicroPython のバージョンとビルド日付machine
-- 基盤ハードウェアの識別子(ボード、CPUなど)
-
uos.
urandom
(n)¶ n 個のランダムバイトを持つバイト列オブジェクトを返します。可能な限り、ハードウェア乱数生成器によって乱数を生成します。
ファイルシステムのアクセス¶
-
uos.
chdir
(path)¶ カレントディレクトリを変更します。
-
uos.
getcwd
()¶ カレントディレクトリのパスを返します。
-
uos.
ilistdir
([dir])¶ この関数はイテレータを返します。イテレータが生成するのは、ディレクトリ内のエントリに対応するタプルです。引数なしの場合はカレントディレクトリを、それ以外の場合は dir で指定したディレクトリをリストします。
タプルの形式は (name, type, inode [, size]) です。
- name は文字列(dir バイト列オブジェクトの場合はバイト列)であり、エントリの名前です。
- type はエントリのタイプを指定する整数で、ディレクトリの場合は 0x4000、通常のファイルの場合は 0x8000 です。
- inode はファイルのiノードに対応する整数であり、そのような概念を持たないファイルシステムについては 0 になります。
- 一部のプラットフォームでは、エントリのサイズを含む4タプルが返されることがあります。ファイルエントリの場合、 size はファイルのサイズを表す整数で、未知の場合は -1 です。現在のところ、ディレクトリエントリについては未定義です。
-
uos.
listdir
([dir])¶ 引数を指定しない場合は、カレントディレクトリ内のエントリを表示します。それ以外の場合は指定されたディレクトリ内のエントリを表示します。
-
uos.
mkdir
(path)¶ 新規にディレクトリを作成します。
-
uos.
remove
(path)¶ ファイルを削除します。
-
uos.
rmdir
(path)¶ ディレクトリを削除します。
-
uos.
rename
(old_path, new_path)¶ ファイルの名前を変更します。
-
uos.
stat
(path)¶ ファイルまたはディレクトリのステータスを取得します。
-
uos.
statvfs
(path)¶ ファイルシステムの状態を取得します。
次の順序でファイルシステム情報を含むタプルを返します。
f_bsize
-- ファイルシステムのブロックサイズf_frsize
-- フラグメントサイズf_blocks
-- f_frsize 単位の fs のサイズf_bfree
-- 空きブロックの数f_bavail
-- 権限なしユーザーのための空きブロック数f_files
-- iノード数f_ffree
-- フリーのiノードの数f_favail
-- 権限なしユーザの空きiノード数f_flag
-- マウントフラグf_namemax
-- 最大ファイル名の長さ
iノードに関連するパラメータ
f_files
,f_ffree
,f_avail
,f_flags
は、ポート固有の実装で使えない場合には 0 になります。
-
uos.
sync
()¶ すべてのファイルシステムを同期します。
ターミナルのリダイレクトと複製¶
-
uos.
dupterm
(stream_object, index=0)¶ 与えた
strean
オブジェクトに MicroPython 端末(REPL)を複製または切り替えを行います。 stream_object の引数はネイティブストリームオブジェクトか、uio.IOBase
から派生してreadinto()
とwrite()
メソッドを実装したものでなければなりません。ストリームは非ブロッキングモードで、readinto()
は読み込み可能なデータがない場合はNone
を返すようにします。この関数を呼び出した後、すべての端末出力がこのストリーム上で繰り返され、ストリーム上で利用可能なすべての入力がターミナル入力に渡されます。
index パラメータは負でない整数であり、設定されている複製を指定します。ポートは2つ以上のスロットを実装できます(スロット 0 は常に使用可能です)。その場合、端末の入出力は設定されているすべてのスロットに複製されます。
stream_object に
None
を渡した場合、 index によって指定されたスロットで重複が取り消されます。この関数は、指定したスロットの前のストリームオブジェクトを返します。
ファイルシステムのマウント¶
いくつかのポートは仮想ファイルシステム(VFS)を提供し、この VFS 内に複数の「実」ファイルシステムをマウントする機能を備えています。ファイルシステムオブジェクトは、VFS のルート、またはルートに存在するサブディレクトリにマウントできます。これにより、Python プログラムで見られるファイルシステムの動的で柔軟な設定が可能になります。この機能を持つポートは mount()
と umount()
関数、そしておそらく VFS クラスで表されるさまざまなファイルシステムの実装を提供します。
-
uos.
mount
(fsobj, mount_point, *, readonly)¶ ファイルシステムオブジェクト fsobj を mount_point 文字列で指定した VFS 内の場所にマウントします。 fsobj には
mount()
メソッドを持つ VFS オブジェクト、またはブロックデバイスを指定できます。ブロックデバイスであればファイルシステムタイプが自動的に検出されます(ファイルシステムが認識されない場合は例外が発生します)。 mount_point が'/'
であれば fsobj をルートににマウントし、'/<name>'
であればルート配下のサブディレクトリにマウントします。readonly が
True
であればファイルシステムが読み取り専用でマウントされています。マウント処理では、ファイルシステムオブジェクトに対してメソッド
mount()
呼出します。mount_point に既にマウントされていれば
OSError(EPERM)
例外が発生します。
-
uos.
umount
(mount_point)¶ ファイルシステムをアンマウントします。 mount_point には、マウント場所を指定する文字列、または以前にマウントされたファイルシステムオブジェクトを指定できます。アンマウント処理では、ファイルシステムオブジェクトに対してメソッド
unmount()
呼出します。"mount_point が見つからなければ
OSError(EINVAL)
例外が発生します。
ブロックデバイス¶
ブロックデバイスは、ブロックプロトコルを実装するオブジェクトです。これは後述する AbstractBlockDev
クラスのメソッドのセットです。このクラスの具象サブクラスでは通常、フラッシュメモリなどのハードウェアの一部にメモリのような機能へのアクセスが許可されます。特定のファイルシステムドライバがブロックデバイスを使用して、ファイルシステム用のデータを格納できます。
さまざまなユースケースをサポートするために、 readblocks
や writeblocks
メソッドには2つの互換性のあるシグネチャがあります(以下を参照)。ブロックデバイスはより、どちらか一方、または両方を実装しています。
-
class
uos.
AbstractBlockDev
(...)¶ ブロックデバイスオブジェクトを構築します。コンストラクタへのパラメータは、特定のブロックデバイスに依存します。
-
readblocks
(block_num, buf)¶
-
readblocks
(block_num, buf, offset) 最初の形式は、整列した複数のブロックを読み取ります。インデックス block_num で指定したブロックを開始点として、デバイスから buf (バイト列)にブロックを読み込みます。読み込むブロック数は buf の長さで与えられ、ブロックサイズの倍数になります。
2番目の形式では、ブロック内の任意の場所、任意の長さで読み取ることができます。ブロックインデックス block_num とブロック内のバイトオフセット offset を開始点として、デバイスから buf (バイト列)にブロックを読み込みます。読み込むブロック数は buf の長さで与えられ、読み込むバイト数になります。
-
writeblocks
(block_num, buf)¶
-
writeblocks
(block_num, buf, offset) 最初の形式は、整列した複数のブロックを書き込みます。書き込む前には、対象のブロックが(必要に応じて)消去されます。インデックス block_num で指定したブロックに buf (バイト列)からブロックを書き込みます。書き込むブロック数は buf の長さで与えられ、ブロックサイズの倍数になります。
2番目の形式では、ブロック内の任意の場所に、任意の長さで書き込むことができます。書き込むバイトのみを変更する必要があり、このメソッドの呼び出し元は、関連するブロックが事前の
ioctl
呼び出しによって消去されることを保証する必要があります。ブロックインデックス block_num とそのブロック内のバイトオフセット offset を開始点として、 buf (バイト配列)からデバイスに書き込みます。書き込むバイト数は buf の長さで指定されます。offset 引数が指定されている場合、たとえゼロであっても、実装がブロックを暗黙的に消去してはならないことに注意してください。
-
ioctl
(op, arg)¶ ブロックデバイスを制御し、そのパラメータを問い合わせます。実行する操作は op に次の整数のうちの1つで指定します。
- 1 -- デバイスを初期化します(arg は未使用)
- 2 -- デバイスをシャットダウンします(arg は未使用)
- 3 -- デバイスを同期します(arg は未使用)
- 4 -- ブロック数のカウントを取得し、整数で返します(arg は未使用)
- 5 -- ブロック内のバイト数を取得し、整数で返します。
None
の場合はデフォルト値の 512 が使われます(arg は未使用) - 6 -- ブロックを消去します。 arg は消去するブロック数です
-
一例として、次のクラスは bytearray
を使って RAM にデータを記憶するブロックデバイスを実装します:
class RAMBlockDev:
def __init__(self, block_size, num_blocks):
self.block_size = block_size
self.data = bytearray(block_size * num_blocks)
def readblocks(self, block_num, buf):
for i in range(len(buf)):
buf[i] = self.data[block_num * self.block_size + i]
def writeblocks(self, block_num, buf):
for i in range(len(buf)):
self.data[block_num * self.block_size + i] = buf[i]
def ioctl(self, op, arg):
if op == 4: # ブロック数を取得
return len(self.data) // self.block_size
if op == 5: # ブロックサイズを取得
return self.block_size
次のように使えます:
import uos
bdev = RAMBlockDev(512, 50)
uos.VfsFat.mkfs(bdev)
vfs = uos.VfsFat(bdev)
uos.mount(vfs, '/ramdisk')
メソッド readblocks()
と writeblocks()
のシグネチャと振舞いの両方をサポートするブロックデバイスの使用例は次のとおりです:
class RAMBlockDev:
def __init__(self, block_size, num_blocks):
self.block_size = block_size
self.data = bytearray(block_size * num_blocks)
def readblocks(self, block, buf, offset=0):
addr = block_num * self.block_size + offset
for i in range(len(buf)):
buf[i] = self.data[addr + i]
def writeblocks(self, block_num, buf, offset=None):
if offset is None:
# do erase, then write
for i in range(len(buf) // self.block_size):
self.ioctl(6, block_num + i)
offset = 0
addr = block_num * self.block_size + offset
for i in range(len(buf)):
self.data[addr + i] = buf[i]
def ioctl(self, op, arg):
if op == 4: # block count
return len(self.data) // self.block_size
if op == 5: # block size
return self.block_size
if op == 6: # block erase
return 0