MicroPython:Библиотеки/uos

Материал из Онлайн справочника
Версия от 20:38, 21 августа 2020; Myagkij (обсуждение | вклад)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Модуль uos – базовые службы «операционной системы»[1]

В этом модуле реализована часть функционала соответствующего модуля CPython. Более подробно читайте в документации к CPython о модуле os.

Модуль uos содержит функции для монтирования и доступа к файловой системе, перенаправления и дупликации терминала, а также функции uname() и urandom().

Функции общего назначения

  • uos.uname() – возвращает кортеж (возможно, именованный кортеж), содержащий информацию об используемом устройстве и/или его операционной системе. В этом кортеже будет пять полей в следующем порядке (каждый из них – строка):
    • sysname – название используемой системы
    • nodename – название сети (может быть тем же самым, что и sysname)
    • release – версия используемой системы
    • version – версия MicroPython и дата создания билда
    • machine – идентификатор используемого устройства (например, платы или CPU)
  • uos.random() – возвращает объект bytes со случайными байтами, количество которых задано в аргументе n. Когда это возможно, возвращаемое значение создается генератором случайных чисел.

Доступ к файловой системе

  • uos.chdir(path) – меняет текущую директорию.
  • uos.getcwd() – считывает текущую директорию.
  • uos.ilistdir([dir]) – возвращает итератор, который в свою очередь возвращает кортежи, соответствующие элементам в обрабатываемой директории dir. Если аргумента dir задано не будет, функция обработает текущую директорию.

Кортежи будут устроены следующим образом (name, type, inode[, size]):

    • name – это название элемента в виде строки (или объекта bytes, если dir – это объект bytes).
    • type – это тип элемента в виде целого числа («0x4000» будет означать директорию, а «0x8000» – обычный файл).
    • inode – это айнод файла в виде целого числа. Здесь может быть «0», если в используемой файловой системе нет такой структуры данных.
    • Некоторые платформы могут вернуть size с информацией о размере элемента. Для файлов это будет целое число, обозначающее размер файла, или «-1», если размер неизвестен. Для директорий значение этого 4-го компонента пока не определено.
  • uos.listdir([dir)] – возвращает список файлов и папок в заданной директории dir. Если директория 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).
    • f_bfree – количество свободных блоков.
    • f_bavail – количество свободных блоков для пользователей без привилегий.
    • f_files – количество айнодов.
    • f_ffree – количество свободных айнодов.
    • f_favail – количество свободных айнодов для пользователей без привилегий.
    • f_flag – флаги с дополнительной информацией о файловой системе (в частности, о том, является ли установленная система только для чтения).
    • f_namemax – максимальный размер названия файла.

Параметры, связанные с айнодами – f_files, f_ffree, f_avail – и параметр f_flags могут вернуть «0», т.к. могут быть недоступны на некоторых MicroPython-портах.

  • uos.sync() – синхронизирует все файловые системы.

Дупликация и перенаправление терминала

  • uos.dupterm(stream_object, index=0, /) – дублирует или переключает терминал MicroPython (REPL) на заданный файлообразный объект. В аргументе stream_object должен быть задан нативный потоковый объект или объект, наследующий от uio.IOBase и поддерживающий методы readinfo() и write(). Этот поток должен быть в неблокирующем режиме, а readinfo() вернет None, если данные для считывания будут отсутствовать.

После вызова этой функции в потоке stream_object будут дублировать все выходные данные терминала, а все данные, входящие в поток stream_object, будут переданы на вход терминала. В аргументе index должно быть неотрицательное целое число – в нем задается слот дупликации. В MicroPython-порте может быть реализовано больше одного слота (слот 0 будет доступен всегда), и если в итоге будет задано несколько слотов, входящие и выходящие данные терминала будут дублироваться на все заданные слоты. Если в аргументе stream_object задано None, то дупликация на слоте index будет прекращена. Функция возвращает предыдущий потокообразный объект на заданном слоте.

Монтирование файловой системы

Некоторые MicroPython-порты поддерживают использование виртуальной файловой системы (VFS) и возможность монтировать с ее помощью несколько «настоящих» файловых систем. Объекты файловой системы можно монтировать либо в корне VFS, либо в поддиректории, находящейся в корне. Это обеспечивает динамичную и гибкую настройку файловой системы, видимой для Python-программ. В MicroPython-портах с таким функционалом поддерживаются функции mount() и unmount(), а также, возможно, разные реализации файловых систем, представленные в классах VFS.

  • uos.mount(fsobj, mount_point, \*, readonly) – монтирует объект файловой системы fsobj в место VFS, заданное в строке mount_point. В аргументе fsobj можно задать VFS-объект, у которого есть метод mount(), или блочное устройство. Если это блочное устройство, то будет автоматически определен тип файловой системы (если файловая система распознана не будет, будет возбуждено исключение). В аргументе mount_point можно задать '/' (это смонтирует fsobj в корень) или '/<name>' (это смонтирует его в поддиректорию, находящуюся в корне).

Если в аргументе readonly задано True, файловая система будет смонтирована только для чтения. Во время монтирования на объекте файловой системы будет вызван метод mount(). Если в mount_point уже что-то смонтировано, это выдаст ошибку OSError(EPERM).

  • uos.umount(mount_point) – демонтирует файловую систему. В аргументе mount_point задается строка с названием места, куда смонтирована файловая система, или объект файловой системы. Во время процесса демонтирования на объекте файловой системы вызывается метод unmount().

Если mount_point найден не будет, это выдаст ошибку OSError(EINVAL).

  • Класс uos.VfsFat(block_dev) – создает объект файловой системы формата FAT. Память для файловой системы обеспечивается с помощью блочного устройства block_dev. Объекты, созданные с помощью этого конструктора, можно монтировать с помощью метода mount().
    • Статический метод mkfs(block_dev) – создает файловую систему типа FAT на block_dev.
  • Класс uos.VfsLfs1(block_dev) – создает объект файловой системы формата littlefs v1. Память для этой файловой системы обеспечивается с помощью блочного устройства block_dev, которое должно поддерживать расширенный интерфейс (см. ниже в разделе «Простой и расширенный интерфейсы»). Объекты, созданные с помощью этого конструктора, можно монтировать с помощью метода mount().

Более подробно читайте в статье «Работа с файловыми системами».

    • Статический метод mkfs(block_dev) – создает файловую систему Lfs1 на блочном устройстве block_dev.

Примечание: Есть информация, что littlefs v1 в некоторых ситуациях дает сбой. Более подробно читайте в GitHub-репорте #347.

  • Класс uos.VfsLfs2(block_dev) – создает объект файловой системы формата littlefs v2. Память для этой файловой системы обеспечивается с помощью блочного устройства block_dev, которое должно поддерживать расширенный интерфейс (см. ниже в разделе «Простой и расширенный интерфейсы»). Объекты, созданные с помощью этого конструктора, можно монтировать с помощью метода mount().

Более подробно читайте в статье «Работа с файловыми системами».

    • Статический метод mkfs(block_dev) – создает файловую систему Lfs2 на блочном устройстве block_dev.

Примечание: Есть информация, что littlefs v2 в некоторых ситуациях дает сбой. Более подробно читайте в GitHub-репорте #295.

Блочные устройства

Блочное устройство – это объект, в котором реализован блочный протокол, который позволяет этому устройству поддерживать файловые системы MicroPython. Работа с физическим оборудованием осуществляется с помощью пользовательских классов (т.е. классов, создаваемых пользователем). Шаблоном для создания таких классов является класс AbstractBlockDev (см. ниже): в MicroPython этот класс в настоящее время не поддерживается, но в классе блочного устройства обязательно должны быть реализованы методы, описанные ниже.

Конкретная реализация этого класса обычно обеспечивает доступ к функционалу для работы с физической памятью (вроде flash-памяти). Блочное устройство можно отформатировать под любую поддерживаемую файловую систему, а потом смонтировать ее с помощью методов модуля uos.

Примеры реализации блочных устройств при помощи двух вариантов блочного протокола, описываемых ниже, ищите в статье «Работа с файловыми системами».

Простой и расширенный интерфейсы

У методов readblocks() и writeblocks() могут быть две совместимые формы – с целью обеспечить гибкость использования (т.е. чтобы их можно было использовать в большом диапазоне ситуаций). В блочном устройстве может быть реализована либо одна из форм, либо обе сразу. Вторая форма (с аргументом offset) считается «расширенным интерфейсом».

Некоторые типы файловых систем (вроде littlefs), которым требуется больше контроля над операциями записи – вроде записи в подблоки без стирания – тоже могут потребовать, чтобы блочное устройство поддерживало расширенный интерфейс.

  • Класс uos.AbstractBlockDev(...) – конструирует объект блочного устройства. Параметры конструктора зависят от используемого блочного устройства.
    • readblocks(block_num, buf) – это первая форма, считывающая выровненные фрагменты данных, чей размер кратен размеру блока. Считывание начинается с блока, заданного в индексном аргументе block_num. Считывание осуществляется из блочного устройства в буфер buf (это массив байтов). Количество считываемых блоков задается размером буфера buf – этот размер должен быть кратен размеру блока.
    • readblocks(block_num, buf, offset) – это вторая «расширенная» форма, позволяющая считывать данные произвольного размера с произвольного места внутри блока. Считывание начинается с блока с индексом block_num. Байт, с которого начинается считывание внутри блока, задается с помощью аргумента offset. Считывание байтов с блочного устройства осуществляется в буфер buf (это массив байтов). Количество считываемых байтов задается размером буфера buf.
    • writeblocks(block_num, buf) – это первая форма, записывающая выровненные фрагменты данных, чей размер кратен размеру блока. Для этой формы требуется, чтобы данные в блоках, куда планируется выполнить запись, сначала были стерты (если необходимо). Запись начинается с блока, заданного в индексном аргументе block_num. Данные записываются в блоки блочного устройства из буфера buf (это массив байтов). Количество записываемых блоков задается размером буфера buf – этот размер должен быть кратен размеру блока.
    • writeblocks(block_num, buf, offset) – это вторая «расширенная» форма, позволяющая записывать данные произвольного размера в произвольное место внутри блока. Изменены должны быть только перезаписываемые байты, а инициатор вызова этого метода сначала должен убедиться, что старые данные в релевантных блоках стерты при помощи метода ioctl() (см. ниже). Запись начинается с блока с индексом block_num. Байт, с которого начинается запись внутри блока, задается с помощью аргумента offset. Запись байтов на блочное устройство осуществляется из буфера buf (это массив байтов). Количество записываемых байтов задается размером буфера buf.

Примечание: Если задан аргумент offset, эти методы никогда не будут неявно стирать данные в блоках – даже если в нем задан «0».

    • ioctl(op, arg) – управляет блочным устройством и делает запросы к его параметрам. Выполняемая операция задается в аргументе op, в котором могут быть указаны следующие значения:
      • 1 – инициализирует блочное устройство (arg не используется)
      • 2 – выключает блочное устройство (arg не используется)
      • 3 – синхронизирует блочное устройство (arg не используется)
      • 4 – считывает количество блоков; возвращает целое число (arg не используется)
      • 5 – считывает количество байтов в блоке; возвращает целое число или None, и в этом случае будет использовано число «512», заданное по умолчанию (arg не используется)
      • 6 – стирает данные в блоке; в аргументе arg задается номер блока

Перехвачена должна быть как минимум функция ioctl(4, ...). В случае файловой системы littlefs также должна быть перехвачена функция ioctl(6, ...). Необходимость в перехвате других функций зависит от используемого «железа». Если не задано что-то другое, функция ioctl(op, arg) возвращает None. Соответственно, неиспользуемые значения выполняемой операции могут быть проигнорированы. Если выполняемая операция перехватывается, то возвращаемым значением для 4-ой операции будет количество блоков, а для 5-ой – количество байтов в блоке (подробнее смотрите в списке выше). Другие операции в случае успеха возвращают «0», а в случае неуспеха – код ошибки OSError.

<syntaxhighlight lang="python" enclose="div">

См.также

Внешние ссылки