micropython — доступ до внутрішніх функцій MicroPython та керування ними

Функції

micropython.const(expr: int) int

Використовується для оголошення виразу константою, щоб компілятор міг його оптимізувати. Ця функція повинна використовуватись так:

from micropython import const

CONST_X = const(123)
CONST_Y = const(2 * CONST_X + 1)

Константи, оголошені таким чином, все ще доступні як глобальні змінні поза модулем, в якому вони оголошені. З іншого боку, якщо ім’я константи починається з підкреслення, вона прихована, недоступна як глобальна змінна і не займає пам’яті під час виконання.

Ця функція const розпізнається безпосередньо парсером MicroPython і надається як частина модуля micropython головним чином для того, щоб скрипти можна було писати у такий спосіб, що вони виконуються як під CPython, так і під MicroPython.

micropython.opt_level(level: int | None = None) int | None

Якщо задано level, ця функція встановлює рівень оптимізації для наступної компіляції скриптів і повертає None. Інакше вона повертає поточний рівень оптимізації.

Рівень оптимізації керує такими функціями компіляції:

  • Твердження: на рівні 0 оператори твердження ввімкнені та компілюються у байт-код; на рівнях 1 і вище твердження не компілюються.

  • Вбудована змінна __debug__: на рівні 0 ця змінна розгортається у True; на рівнях 1 і вище вона розгортається у False.

  • Номери рядків вихідного коду: на рівнях 0, 1 і 2 номери рядків зберігаються разом із байт-кодом, щоб винятки могли повідомляти про номер рядка, де вони виникли; на рівнях 3 і вище номери рядків не зберігаються.

За замовчуванням рівень оптимізації зазвичай дорівнює 0.

micropython.alloc_emergency_exception_buf(size: int) None

Виділяє size байтів RAM для буфера аварійних винятків (гарний розмір — близько 100 байтів). Буфер використовується для створення винятків у випадках, коли звичайне виділення RAM зазнає невдачі (наприклад, всередині обробника переривань), і таким чином надає корисну інформацію трасування в таких ситуаціях.

Хороший спосіб використання цієї функції — помістити її на початок основного скрипта (наприклад, boot.py або main.py), тоді буфер аварійних винятків буде активний для всього наступного коду.

micropython.mem_info(verbose: Any | None = None) None

Виводить інформацію про поточно використовувану пам’ять. Якщо задано аргумент verbose, виводиться додаткова інформація.

Виведена інформація залежить від реалізації, але наразі включає обсяг використаного стеку та купи. У режимі verbose виводиться вся купа з позначенням використаних і вільних блоків.

micropython.qstr_info(verbose: Any | None = None) None

Виводить інформацію про поточно інтерновані рядки. Якщо задано аргумент verbose, виводиться додаткова інформація.

Виведена інформація залежить від реалізації, але наразі включає кількість інтернованих рядків та обсяг RAM, який вони займають. У режимі verbose виводяться імена всіх інтернованих у RAM рядків.

micropython.stack_use() int

Повертає ціле число, що представляє поточний обсяг використаного стеку. Абсолютне значення саме по собі не є особливо корисним; його слід використовувати для обчислення різниці у використанні стеку в різних точках.

micropython.heap_lock() None

Блокує купу. Поки заблокована, жодне виділення пам’яті не може відбутися, і MemoryError буде згенерований при будь-якій спробі виділення з купи.

Блокування вкладається: багаторазовий виклик heap_lock() збільшує глибину блокування. Купа залишається заблокованою, доки heap_unlock() не буде викликано стільки ж разів.

Якщо REPL стає активним при заблокованій купі, блокування буде примусово знято.

micropython.heap_unlock() int

Зменшує глибину блокування купи на одиницю та повертає нову глибину як невід’ємне ціле число. Повернене значення 0 означає, що купа більше не заблокована і виділення знову дозволені.

micropython.heap_locked() int

Повертає поточну глибину блокування купи як невід’ємне ціле число; 0 означає, що купа не заблокована.

Примітка: ця функція недоступна на OpenMV Cam.

micropython.kbd_intr(chr: int) None

Встановлює символ, що генерує виняток KeyboardInterrupt. За замовчуванням під час виконання скрипта встановлено значення 3, що відповідає Ctrl-C. Передача -1 цій функції вимкне перехоплення Ctrl-C, передача 3 відновить його.

Цю функцію можна використовувати для запобігання перехопленню Ctrl-C у вхідному потоці символів, який зазвичай використовується для REPL, якщо цей потік використовується для інших цілей.

micropython.schedule(func: Callable[[Any], Any], arg: Any) None

Планує виконання функції func «дуже скоро». Функції передається значення arg як єдиний аргумент. «Дуже скоро» означає, що середовище виконання MicroPython докладе всіх зусиль для виконання функції якнайшвидше, враховуючи, що воно також намагається бути ефективним, і за умови, що виконуються такі умови:

  • Запланована функція ніколи не буде витісняти іншу заплановану функцію.

  • Заплановані функції завжди виконуються «між кодами операцій», тобто всі фундаментальні операції Python (наприклад, додавання до списку) гарантовано є атомарними.

  • Певний порт може визначати «критичні регіони», у яких заплановані функції ніколи не виконуються. Функції можуть бути заплановані всередині критичного регіону, але вони не будуть виконані до виходу з нього. Прикладом критичного регіону є обробник переривань із витісненням (IRQ).

  • Всередині функцій рідного коду заплановані функції не викликаються, якщо рідний код не викликає функцію, яка це робить спеціально.

  • Певні функції, включаючи poll.poll, poll.ipoll, time.sleep та time.sleep_ms (включаючи затримки нульової тривалості), викликатимуть заплановані функції.

Одне з застосувань цієї функції — планування зворотного виклику з IRQ із витісненням. Такий IRQ накладає обмеження на код, що виконується в IRQ (наприклад, купа може бути заблокована), і планування функції для виклику пізніше знімає ці обмеження.

На багатопотокових портах поведінка запланованої функції залежить від того, чи увімкнено Глобальне блокування інтерпретатора (GIL) для конкретного порту:

  • Якщо GIL увімкнено, функція може витісняти будь-який потік і виконуватися в його контексті.

  • Якщо GIL вимкнено, функція буде витісняти лише головний потік і виконуватися в його контексті.

Примітка: якщо schedule() викликається з IRQ із витісненням, коли виділення пам’яті не дозволено, і зворотний виклик, що передається до schedule(), є прив’язаним методом, пряма передача зазнає невдачі. Це пов’язано з тим, що створення посилання на прив’язаний метод спричиняє виділення пам’яті. Рішення полягає у створенні посилання на метод у конструкторі класу та передачі цього посилання до schedule(). Це детально обговорюється тут довідкова документація у розділі «Створення об’єктів Python».

Існує обмежена черга для зберігання запланованих функцій, і schedule() генерує RuntimeError, якщо черга повна.

Класи

class micropython.RingIO(size: int)
class micropython.RingIO(buffer: bytes | bytearray | memoryview)

Надає буфер кільця фіксованого розміру для байтів зі стрімовим інтерфейсом. Може вважатися варіантом FIFO-черги для io.BytesIO. Дві форми конструктора відрізняються лише способом надання резервного буфера:

  • RingIO(size) виділяє резервний буфер внутрішньо. Класичний алгоритм кільцевого буфера резервує один байт для відстеження, тому виділений буфер на один байт більше ніж size, і екземпляр може зберігати повні size байтів даних. Наприклад, RingIO(16) виділяє буфер на 17 байтів і зберігає 16 байтів даних.

  • RingIO(buffer) використовує наданий buffer безпосередньо, не виділяючи новий. Оскільки один байт резервується для відстеження, екземпляр може зберігати len(buffer) - 1 байтів даних. Наприклад, RingIO(bytearray(16)) зберігає 15 байтів даних.

Екземпляр RingIO є безпечним для використання з IRQ/потоками при передачі даних в одному напрямку (наприклад, запис з IRQ та читання з функції поза IRQ, або навпаки). Це не виконується, якщо один екземпляр записується як з IRQ, так і з не-IRQ контекстів, що часто призводить до пошкодження даних.

any() int

Повертає ціле число, що вказує кількість символів, доступних для читання.

read(nbytes: int | None = None) bytes

Читає доступні символи. Це неблокуюча функція. Якщо вказано nbytes, читає щонайбільше стільки байтів, інакше читає якомога більше даних.

Повернене значення: об’єкт bytes, що містить прочитані байти. Буде об’єктом bytes нульової довжини, якщо даних немає.

readline(nbytes: int | None = None) bytes

Читає рядок, що закінчується символом нового рядка, або повертає його, якщо такий є в буфері, інакше повертає доступні байти з буфера. Якщо вказано nbytes, читає щонайбільше стільки байтів.

Повернене значення: об’єкт bytes, що містить прочитаний рядок.

readinto(buf: bytearray | memoryview, nbytes: int | None = None) int

Читає доступні байти у наданий buf. Якщо вказано nbytes, читає щонайбільше стільки байтів. Інакше читає щонайбільше len(buf) байтів.

Повернене значення: ціле число, що вказує кількість байтів, прочитаних у buf.

write(buf: bytes | bytearray | memoryview) int

Неблокуючий запис байтів із buf до кільцевого буфера, обмежений доступним місцем у кільцевому буфері.

Повернене значення: ціле число, що вказує кількість записаних байтів.

close() None

Заглушка, надана як частина стандартного інтерфейсу stream. Не впливає на дані у кільцевому буфері.