2016-04-26 23:55:06 +01:00
|
|
|
:mod:`uos` -- basic "operating system" services
|
2016-04-27 12:11:27 +01:00
|
|
|
===============================================
|
2014-10-31 01:37:19 +00:00
|
|
|
|
2016-04-26 23:55:06 +01:00
|
|
|
.. module:: uos
|
2014-10-31 01:37:19 +00:00
|
|
|
:synopsis: basic "operating system" services
|
|
|
|
|
2017-07-02 13:37:31 +01:00
|
|
|
|see_cpython_module| :mod:`python:os`.
|
|
|
|
|
2018-03-07 03:49:25 +00:00
|
|
|
The ``uos`` module contains functions for filesystem access and mounting,
|
|
|
|
terminal redirection and duplication, and the ``uname`` and ``urandom``
|
|
|
|
functions.
|
2014-10-31 01:37:19 +00:00
|
|
|
|
2018-03-07 03:49:25 +00:00
|
|
|
General functions
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
.. function:: 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
|
|
|
|
* ``nodename`` -- the network name (can be the same as ``sysname``)
|
|
|
|
* ``release`` -- the version of the underlying system
|
|
|
|
* ``version`` -- the MicroPython version and build date
|
|
|
|
* ``machine`` -- an identifier for the underlying hardware (eg board, CPU)
|
|
|
|
|
|
|
|
.. function:: urandom(n)
|
|
|
|
|
|
|
|
Return a bytes object with *n* random bytes. Whenever possible, it is
|
|
|
|
generated by the hardware random number generator.
|
|
|
|
|
|
|
|
Filesystem access
|
|
|
|
-----------------
|
2014-10-31 01:37:19 +00:00
|
|
|
|
|
|
|
.. function:: chdir(path)
|
|
|
|
|
|
|
|
Change current directory.
|
|
|
|
|
|
|
|
.. function:: getcwd()
|
|
|
|
|
|
|
|
Get the current directory.
|
|
|
|
|
2017-05-10 03:44:21 +01:00
|
|
|
.. function:: ilistdir([dir])
|
|
|
|
|
2018-03-09 00:02:26 +00:00
|
|
|
This function returns an iterator which then yields tuples corresponding to
|
2017-05-10 03:44:21 +01:00
|
|
|
the entries in the directory that it is listing. With no argument it lists the
|
2017-06-27 22:37:47 +01:00
|
|
|
current directory, otherwise it lists the directory given by *dir*.
|
2017-05-10 03:44:21 +01:00
|
|
|
|
2018-03-09 00:02:26 +00:00
|
|
|
The tuples have the form *(name, type, inode[, size])*:
|
2017-05-10 03:44:21 +01:00
|
|
|
|
2017-06-27 22:37:47 +01:00
|
|
|
- *name* is a string (or bytes if *dir* is a bytes object) and is the name of
|
2017-05-10 03:44:21 +01:00
|
|
|
the entry;
|
2017-06-27 22:37:47 +01:00
|
|
|
- *type* is an integer that specifies the type of the entry, with 0x4000 for
|
2017-05-10 03:44:21 +01:00
|
|
|
directories and 0x8000 for regular files;
|
2017-06-27 22:37:47 +01:00
|
|
|
- *inode* is an integer corresponding to the inode of the file, and may be 0
|
2017-05-10 03:44:21 +01:00
|
|
|
for filesystems that don't have such a notion.
|
2018-03-09 00:02:26 +00:00
|
|
|
- Some platforms may return a 4-tuple that includes the entry's *size*. 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.
|
2017-05-10 03:44:21 +01:00
|
|
|
|
2014-10-31 01:37:19 +00:00
|
|
|
.. function:: listdir([dir])
|
|
|
|
|
|
|
|
With no argument, list the current directory. Otherwise list the given directory.
|
|
|
|
|
|
|
|
.. function:: mkdir(path)
|
|
|
|
|
|
|
|
Create a new directory.
|
|
|
|
|
|
|
|
.. function:: remove(path)
|
|
|
|
|
|
|
|
Remove a file.
|
|
|
|
|
|
|
|
.. function:: rmdir(path)
|
|
|
|
|
|
|
|
Remove a directory.
|
|
|
|
|
2015-05-11 01:30:56 +01:00
|
|
|
.. function:: rename(old_path, new_path)
|
|
|
|
|
|
|
|
Rename a file.
|
|
|
|
|
2014-10-31 01:37:19 +00:00
|
|
|
.. function:: stat(path)
|
|
|
|
|
|
|
|
Get the status of a file or directory.
|
|
|
|
|
2017-04-05 09:44:10 +01:00
|
|
|
.. function:: 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
|
|
|
|
* ``f_frsize`` -- fragment size
|
|
|
|
* ``f_blocks`` -- size of fs in f_frsize units
|
|
|
|
* ``f_bfree`` -- number of free blocks
|
2019-02-13 01:29:01 +00:00
|
|
|
* ``f_bavail`` -- number of free blocks for unprivileged users
|
2017-04-05 09:44:10 +01:00
|
|
|
* ``f_files`` -- number of inodes
|
|
|
|
* ``f_ffree`` -- number of free inodes
|
2019-02-13 01:29:01 +00:00
|
|
|
* ``f_favail`` -- number of free inodes for unprivileged users
|
2017-04-05 09:44:10 +01:00
|
|
|
* ``f_flag`` -- mount flags
|
|
|
|
* ``f_namemax`` -- maximum filename length
|
|
|
|
|
|
|
|
Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail``
|
|
|
|
and the ``f_flags`` parameter may return ``0`` as they can be unavailable
|
|
|
|
in a port-specific implementation.
|
2016-09-27 10:29:31 +01:00
|
|
|
|
2014-10-31 01:37:19 +00:00
|
|
|
.. function:: sync()
|
|
|
|
|
|
|
|
Sync all filesystems.
|
|
|
|
|
2018-03-07 03:49:25 +00:00
|
|
|
Terminal redirection and duplication
|
|
|
|
------------------------------------
|
2014-10-31 01:37:19 +00:00
|
|
|
|
2017-06-14 07:02:57 +01:00
|
|
|
.. function:: dupterm(stream_object, index=0)
|
2015-06-10 22:29:56 +01:00
|
|
|
|
2017-12-04 16:36:20 +00:00
|
|
|
Duplicate or switch the MicroPython terminal (the REPL) on the given `stream`-like
|
2019-02-23 22:13:51 +00:00
|
|
|
object. The *stream_object* argument must be a native stream object, or derive
|
|
|
|
from ``uio.IOBase`` and implement the ``readinto()`` and
|
2017-06-14 07:02:57 +01:00
|
|
|
``write()`` methods. The stream should be in non-blocking mode and
|
|
|
|
``readinto()`` should return ``None`` if 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 ``None`` is 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.
|
2018-03-07 03:50:38 +00:00
|
|
|
|
|
|
|
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 :func:`mount` and
|
|
|
|
:func:`umount` functions, and possibly various filesystem implementations
|
|
|
|
represented by VFS classes.
|
|
|
|
|
|
|
|
.. function:: 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 ``True`` then 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.
|
|
|
|
|
|
|
|
.. function:: 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:: VfsFat(block_dev)
|
|
|
|
|
|
|
|
Create a filesystem object that uses the FAT filesystem format. Storage of
|
|
|
|
the FAT filesystem is provided by *block_dev*.
|
|
|
|
Objects created by this constructor can be mounted using :func:`mount`.
|
|
|
|
|
|
|
|
.. staticmethod:: mkfs(block_dev)
|
|
|
|
|
|
|
|
Build a FAT filesystem on *block_dev*.
|
|
|
|
|
|
|
|
Block devices
|
|
|
|
-------------
|
|
|
|
|
|
|
|
A block device is an object which implements the block protocol, which is a set
|
|
|
|
of methods described below by the :class:`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:: AbstractBlockDev(...)
|
|
|
|
|
|
|
|
Construct a block device object. The parameters to the constructor are
|
|
|
|
dependent on the specific block device.
|
|
|
|
|
|
|
|
.. method:: readblocks(block_num, buf)
|
|
|
|
|
2018-06-28 04:25:10 +01:00
|
|
|
Starting at the block given by the index *block_num*, read blocks from
|
|
|
|
the device into *buf* (an array of bytes).
|
|
|
|
The number of blocks to read is given by the length of *buf*,
|
2018-03-07 03:50:38 +00:00
|
|
|
which will be a multiple of the block size.
|
|
|
|
|
|
|
|
.. method:: writeblocks(block_num, buf)
|
|
|
|
|
2018-06-28 04:25:10 +01:00
|
|
|
Starting at the block given by the index *block_num*, write blocks from
|
|
|
|
*buf* (an array of bytes) to the device.
|
|
|
|
The number of blocks to write is given by the length of *buf*,
|
2018-03-07 03:50:38 +00:00
|
|
|
which will be a multiple of the block size.
|
|
|
|
|
|
|
|
.. method:: 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 ``None`` in which case the default value of 512 is used
|
|
|
|
(*arg* is unused)
|
|
|
|
|
|
|
|
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):
|
|
|
|
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
|
|
|
|
|
|
|
|
It can be used as follows::
|
|
|
|
|
|
|
|
import uos
|
|
|
|
|
|
|
|
bdev = RAMBlockDev(512, 50)
|
|
|
|
uos.VfsFat.mkfs(bdev)
|
|
|
|
vfs = uos.VfsFat(bdev)
|
|
|
|
uos.mount(vfs, '/ramdisk')
|