uos-basic "operating system" services

This module implements a subset of the corresponding CPython module, as described below. For more information, please refer to the original CPython documentation: os.

The uos module contains functions for file system access and mounting, terminal redirection and copying, and uname and urandom.

Common functions

uos.uname()

Return a tuple (perhaps a named tuple) containing information about the underlying machine and/or its operating system. The tuple has five fields in the following order, and each field is a string:

  • sysname-the name of the underlying system
  • nodename-node name (/board name) (can be the same as sysname)
  • release-the version of the underlying system
  • version-MicroPython version and build date
  • machine-the identifier of the underlying hardware (for example, board, CPU)

uos.urandom(n)

Returns a bytes object containing n random bytes. Whenever possible, it is generated by a hardware random number generator.

File system access

uos.chdir(path)

Change the current directory.

uos.getcwd()

Get the current directory.

uos.ilistdir([dir])

This function returns an iterator and then generates tuples corresponding to the entries in the listed directories. If no parameter is passed, it lists the current directory, otherwise it lists the directory given by dir.

Tuples have the form (name, type, inode[, size]):

  • name: is a string (if dir is a bytes object, then bytes), and is the name of the entry;
  • type: is an integer that specifies the type of entry, the directory is 0x4000, and the regular file is 0x8000;
  • inode: is an integer corresponding to the file inode, and it can be 0 for file systems without this concept.
  • Some platforms may return a 4-tuple containing the size of the entry. For file entries, size is an integer representing the size of the file, or -1 if unknown. The meaning of the current entry is currently undefined.

uos.listdir([dir])

If there are no parameters, please list the current directory. Otherwise, list the given directory.

uos.mkdir(path)

Create a new directory.

uos.remove(path)

Delete Files.

uos.rmdir(path)

Delete the directory.

uos.rename (old_path, new_path)

Rename the file.

uos.stat(path)

Get the status of a file or directory.

uos.statvfs(path)

Get the status of the file system.

Return a tuple containing file system information in the following order:

  • f_bsize-file system block size
  • f_frsize-fragment size
  • f_blocks-the size of fs in f_frsize unit
  • f_bfree-the number of free blocks
  • f_bavail-the number of free blocks for unprivileged users
  • f_files-number of inodes
  • f_ffree-the number of free inodes
  • f_favail-the number of free inodes for unprivileged users
  • f_flag-mount flag
  • f_namemax-maximum file name length

Parameters related to inodes: f_files, f_ffree, f_avail and f_flags parameters may return '0` because they are not available in hardware-specific implementations.

uos.sync()

Synchronize all file systems.

Terminal redirection and copy

uos.dupterm(stream_object, index = 0)

Copy or switch the MicroPython terminal (REPL) on the given stream class object. The stream_object parameter must implement the readinto() and write() methods. The stream should be in non-blocking mode. If there is no data available for reading, readinto() should return'None`.

After calling this function, all terminal output will be repeated on this stream, and any input available on the stream will be passed to the terminal input.

The index parameter should be a non-negative integer and specify the set replication slot. A given port can implement multiple slots (slot 0 will always be available), and in this case, terminal input and output are replicated on all set slots.

If None is passed as a stream_object, the copy is canceled on the slot given by the index.

This function returns the previous stream-like object in the given slot.

File system mount

Some ports provide a virtual file system (VFS) and the ability to install multiple "real" file systems in this VFS. File system objects can be installed in the root directory of the VFS, or in subdirectories in the root directory. This allows dynamic and flexible configuration of the file system seen by the Python program. Ports with this function provide mount() and umount() functions, as well as various file system implementations that may be represented by the VFS class.

uos.mount(fsobj, mount_point, *, readonly)

Mount the file system object fsobj to the location in the VFS specified by the mount_point string. fsobj can be a VFS object with a mount() method or a block device. If it is a block device, the file system type is automatically detected (if the file system is not recognized, an exception will be raised). mount_point can be'/' to mount fsobj under the root directory, or'/ ' to mount to a subdirectory under the root directory.

If readonly is "True", the file system is mounted as read-only.

During the mount process, the mount() method is called on the file system object.

If mount_point is already mounted, OSError(EPERM) will be raised.

uos.umount(mount_point)

Unmount the file system. mount_point can be a string naming the location of the mount, or it can be a previously mounted file system object. During the unmounting process, the method umount() is called on the file system object.

If mount_point cannot be found, OSError (EINVAL) will be raised.

class uos.VfsFat(block_dev)

Create a file system object formatted using the FAT file system. The storage of the FAT file system is provided by block_dev. You can use mount() to mount the object created by this constructor.

static mkfs(block_dev)

Build a FAT file system on block_dev.

File system formatting

In MaixPy, we provide an operation to format the flash file system. If users want to clear the flash file system, they can use the interface flash_format to achieve

uos.flash_format()

This interface does not need to pass in parameters, directly use will format the flash of the development board. Please note that formatting will clear all files, please make sure that all files in flash need to be deleted before use

Block device

A block device is an object that implements a block protocol, which is a set of methods described by the AbstractBlockDev class below. Specific implementations of this type usually allow access to memory-like functions as hardware (such as flash memory). Specific file system drivers can use block devices to store data in their file system.

class uos.AbstractBlockDev()...)

The building block device object. The parameters of the constructor depend on the specific block device.

readblocks(block_num, buf)

Starting from the block given by the index block_num, read the block from the device into buf (byte array). The number of blocks to be read is given by the length of buf, which will be a multiple of the block size.

writeblocks(block_num, buf)

Starting from the block given by the index block_num, write the block in buf (byte array) to the device. The number of blocks to be written is given by the length of buf, which will be a multiple of the block size.

ioctl(op, arg)

Control the block device and query its parameters. The operation to be performed is given by op, which is one of the following integers:

  • 1-Initialize the device (arg is not used)
  • 2-Turn off the device (arg is not used)
  • 3-Synchronization device (arg is not used)
  • 4-Get the count of the number of blocks, it should return an integer (arg is not used)
  • 5-Get the number of bytes in the block, it should return an integer, or "None", in this case the default value 512 is used (arg is not used)

Routine

Routine 1

Taking fat32 as an example, the following class will implement a block device that uses bytearray to store its data in 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: # get number of blocks
            return len(self.data) // self.block_size
        if op == 5: # get block size
            return self.block_size

or:

import uos

bdev = RAMBlockDev(512, 50)
uos.VfsFat.mkfs(bdev)
vfs = uos.VfsFat(bdev)
uos.mount(vfs,'/ramdisk')

Routine 2

Taking spiffs as an example, the following class will implement a block device, which uses bytearray to store its data in RAM:


class RAMFlashDev:
    def __init__(self):
            self.fs_size = 256*1024
            self.fs_data = bytearray(256*1024)
            self.erase_block = 32*1024
            self.log_block_size = 64*1024
            self.log_page_size = 4*1024
    def read(self,buf,size,addr):
            for i in range(len(buf)):
                buf[i] = self.fs_data[addr+i]
    def write(self,buf,size,addr):
            for i in range(len(buf)):
                self.fs_data[addr+i] = buf[i]
    def erase(self,size,addr):
            for i in range(size):
                self.fs_data[addr+i] = 0xff


blkdev = RAMFlashDev.RAMFlashDev()
vfs = uos.VfsSpiffs(blkdev)
vfs.mkfs(vfs)
uos.mount(vfs,'/ramdisk')