uos – basic “operating system” services¶
This module implements a subset of the corresponding CPython module,
as described below. For more information, refer to the original
CPython documentation: os.
The uos module contains functions for filesystem access and mounting,
terminal redirection and duplication, and the uname function.
General functions¶
- uos.uname()¶
Return a tuple (possibly a named tuple) containing information about the underlying machine and/or its operating system. The tuple has five fields in the following order, each of them being a string:
sysname– the name of the underlying system. “Lego Technic Large Hub”nodename– the network name. “LEGO Learning System Hub”release– the version of the underlying system. The MicroPython release number on which this is based.version– a more exact MicroPython version and build datemachine– an identifier for the underlying hardware (eg board, CPU). “Lego Technic Large Hub with STM32F413xx”
Difference for RI5
The function uos.urandom() from the base MicroPython version is not implemented on the RI5
Constants¶
- uos.sep¶
Filesystem path separator ‘'
Difference for RI5
This constant is no longer noted in the base MicroPython docs version.
Filesystem access¶
- uos.chdir(path)¶
Change current directory.
- uos.getcwd()¶
Get the current directory.
- uos.ilistdir([dir])¶
This function returns an iterator which then yields tuples corresponding to the entries in the directory that it is listing. With no argument it lists the current directory, otherwise it lists the directory given by dir.
The tuples have the form (name, type, inode, size):
name is a string (or bytes if dir is a bytes object) and is the name of the entry;
type is an integer that specifies the type of the entry, with 0x4000 for directories and 0x8000 for regular files;
inode is an integer corresponding to the inode of the file, and may be 0 for filesystems that don’t have such a notion.
For file entries, size is an integer representing the size of the file or -1 if unknown. Its meaning is currently undefined for directory entries.
- uos.listdir([dir])¶
With no argument, list the current directory. Otherwise list the given directory.
- uos.mkdir(path)¶
Create a new directory.
- uos.remove(path)¶
Remove a file. unlink() is also available and is semantically identical to this.
- uos.rmdir(path)¶
Remove a directory.
- uos.rename(old_path, new_path)¶
Rename a file.
- uos.stat(path)¶
Get the status of a file or directory.
- uos.statvfs(path)¶
Get the status of a fileystem.
Returns a tuple with the filesystem information in the following order:
f_bsize– file system block size. 4096 for the RI5.f_frsize– fragment size. 4096 for the RI5.f_blocks– size of fs in f_frsize units. 7936 for the RI5.f_bfree– number of free blocks.f_bavail– number of free blocks for unpriviliged usersf_files– number of inodes. 0 for the RI5.f_ffree– number of free inodes. 0 for the RI5.f_favail– number of free inodes for unpriviliged users. 0 for the RI5.f_flag– mount flags. 0 for the RI5.f_namemax– maximum filename length. 255 for the RI5.
- uos.sync()¶
Sync all filesystems.
Terminal redirection and duplication¶
- uos.dupterm(stream_object, index=0)¶
Duplicate or switch the MicroPython terminal (the REPL) on the given
stream-like object. The stream_object argument must be a native stream object, or derive fromuio.IOBaseand implement thereadinto()andwrite()methods. The stream should be in non-blocking mode andreadinto()should returnNoneif there is no data available for reading.After calling this function all terminal output is repeated on this stream, and any input that is available on the stream is passed on to the terminal input.
The index parameter should be a non-negative integer and specifies which duplication slot is set. A given port may implement more than one slot (slot 0 will always be available) and in that case terminal input and output is duplicated on all the slots that are set.
If
Noneis passed as the stream_object then duplication is cancelled on the slot given by index.The function returns the previous stream-like object in the given slot.
Filesystem mounting¶
Some ports provide a Virtual Filesystem (VFS) and the ability to mount multiple
“real” filesystems within this VFS. Filesystem objects can be mounted at either
the root of the VFS, or at a subdirectory that lives in the root. This allows
dynamic and flexible configuration of the filesystem that is seen by Python
programs. Ports that have this functionality provide the mount() and
umount() functions, and possibly various filesystem implementations
represented by VFS classes.
- uos.mount(fsobj, mount_point, \*, readonly)¶
Mount the filesystem object fsobj at the location in the VFS given by the mount_point string. fsobj can be a a VFS object that has a
mount()method, or a block device. If it’s a block device then the filesystem type is automatically detected (an exception is raised if no filesystem was recognised). mount_point may be'/'to mount fsobj at the root, or'/<name>'to mount it at a subdirectory under the root.If readonly is
Truethen the filesystem is mounted read-only.During the mount process the method
mount()is called on the filesystem object.Will raise
OSError(EPERM)if mount_point is already mounted.
- uos.umount(mount_point)¶
Unmount a filesystem. mount_point can be a string naming the mount location, or a previously-mounted filesystem object. During the unmount process the method
umount()is called on the filesystem object.Will raise
OSError(EINVAL)if mount_point is not found.
- class uos.VfsLfs1(block_dev)¶
Create a filesystem object that uses the littlefs v1 filesystem format. Storage of the littlefs filesystem is provided by block_dev. Objects created by this constructor can be mounted using
mount().- static mkfs(block_dev)¶
Build a littlefs filesystem on block_dev.
Difference for RI5
The base MicroPython version uses a VfsFat filesystem. The RI5 replaces that with VfsLfs1. This also means that block devices below use the extended interface so need to implement the offset parameter when doing reads and writes.
Block devices¶
A block device is an object which implements the block protocol, which is a set
of methods described below by the AbstractBlockDev class. A concrete
implementation of this class will usually allow access to the memory-like
functionality a piece of hardware (like flash memory). A block device can be
used by a particular filesystem driver to store the data for its filesystem.
- class uos.AbstractBlockDev(...)¶
Construct a block device object. The parameters to the constructor are dependent on the specific block device.
- readblocks(block_num, buf, offset)¶
Starting at the block given by the index block_num and from offset bytes into that block, read blocks from the device into buf (an array of bytes). The number of blocks to read is given by the length of buf.
- writeblocks(block_num, buf, offset)¶
Starting at the block given by the index block_num and from offset bytes into that block, write blocks from buf (an array of bytes) to the device. The number of blocks to write is given by the length of buf.
- ioctl(op, arg)¶
Control the block device and query its parameters. The operation to perform is given by op which is one of the following integers:
1 – initialise the device (arg is unused)
2 – shutdown the device (arg is unused)
3 – sync the device (arg is unused)
4 – get a count of the number of blocks, should return an integer (arg is unused)
5 – get the number of bytes in a block, should return an integer, or
Nonein which case the default value of 512 is used (arg is unused)6 – erase a block (arg is the block number to erase)
By way of example, the following class will implement a block device that stores
its data in RAM using a bytearray:
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, offset):
for i in range(len(buf)):
buf[i] = self.data[block_num * self.block_size + offset + i]
def writeblocks(self, block_num, buf, offset):
for i in range(len(buf)):
self.data[block_num * self.block_size + offset + i] = buf[i]
def ioctl(self, op, arg):
if op == 4: # get number of blocks
return len(self.data) // self.block_size
if op == 5: # get block size
return self.block_size
if op == 6: # erase block
self.writeblocks(arg, bytearray(self.block_size), 0)
It should be able to be used as follows, although this currently seems to fail with a TypeError on RI5 (so maybe something else is missing from the above):
import uos
bdev = RAMBlockDev(512, 50)
uos.VfsFat.mkfs(bdev)
vfs = uos.VfsFat(bdev)
uos.mount(vfs, '/ramdisk')