micropython — acceso y control de los componentes internos de MicroPython

Funciones

micropython.const(expr: int) int

Se usa para declarar que la expresión es una constante de modo que el compilador pueda optimizarla. El uso de esta función debe ser el siguiente:

from micropython import const

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

Las constantes declaradas de esta manera siguen siendo accesibles como variables globales desde fuera del módulo en el que se declaran. Por otro lado, si una constante comienza con un guion bajo, queda oculta, no está disponible como variable global y no ocupa memoria durante la ejecución.

Esta función const es reconocida directamente por el analizador de MicroPython y se proporciona como parte del módulo micropython principalmente para que se puedan escribir scripts que funcionen tanto en CPython como en MicroPython, siguiendo el patrón anterior.

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

Si se proporciona level, esta función establece el nivel de optimización para la compilación posterior de scripts y devuelve None. De lo contrario, devuelve el nivel de optimización actual.

El nivel de optimización controla las siguientes características de compilación:

  • Aserciones: en el nivel 0 las sentencias de aserción están habilitadas y se compilan en el bytecode; en los niveles 1 y superiores las aserciones no se compilan.

  • Variable integrada __debug__: en el nivel 0 esta variable se expande a True; en los niveles 1 y superiores se expande a False.

  • Números de línea del código fuente: en los niveles 0, 1 y 2 los números de línea del código fuente se almacenan junto con el bytecode para que las excepciones puedan informar de la línea en la que ocurrieron; en los niveles 3 y superiores los números de línea no se almacenan.

El nivel de optimización predeterminado suele ser el nivel 0.

micropython.alloc_emergency_exception_buf(size: int) None

Reserva size bytes de RAM para el búfer de excepciones de emergencia (un buen tamaño es alrededor de 100 bytes). El búfer se usa para crear excepciones en los casos en que la asignación normal de RAM fallaría (por ejemplo, dentro de un manejador de interrupciones) y, por tanto, proporcionar información útil de seguimiento (traceback) en esas situaciones.

Una buena manera de usar esta función es colocarla al principio de su script principal (por ejemplo, boot.py o main.py) y así el búfer de excepciones de emergencia estará activo para todo el código que le siga.

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

Imprime información sobre la memoria actualmente en uso. Si se proporciona el argumento verbose, se imprime información adicional.

La información que se imprime depende de la implementación, pero actualmente incluye la cantidad de pila (stack) y de montón (heap) utilizados. En modo detallado imprime todo el montón indicando qué bloques están en uso y cuáles están libres.

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

Imprime información sobre las cadenas internadas (interned) actualmente. Si se proporciona el argumento verbose, se imprime información adicional.

La información que se imprime depende de la implementación, pero actualmente incluye el número de cadenas internadas y la cantidad de RAM que usan. En modo detallado imprime los nombres de todas las cadenas internadas en RAM.

micropython.stack_use() int

Devuelve un entero que representa la cantidad actual de pila que se está utilizando. El valor absoluto de este número no es particularmente útil; más bien debe usarse para calcular diferencias en el uso de la pila en distintos puntos.

micropython.heap_lock() None

Bloquea el montón. Mientras está bloqueado, no puede producirse ninguna asignación de memoria y se lanzará un MemoryError si se intenta cualquier asignación en el montón.

Los bloqueos se anidan: llamar a heap_lock() varias veces aumenta la profundidad del bloqueo. El montón permanece bloqueado hasta que se haya llamado a heap_unlock() el mismo número de veces.

Si el REPL se activa con el montón bloqueado, este se desbloqueará forzosamente.

micropython.heap_unlock() int

Disminuye en uno la profundidad de bloqueo del montón y devuelve la nueva profundidad como un entero no negativo. Un valor de retorno de 0 significa que el montón ya no está bloqueado y que las asignaciones vuelven a estar permitidas.

micropython.heap_locked() int

Devuelve la profundidad de bloqueo actual del montón como un entero no negativo; 0 significa que el montón no está bloqueado.

Nota: esta función no está disponible en la OpenMV Cam.

micropython.kbd_intr(chr: int) None

Establece el carácter que lanzará una excepción KeyboardInterrupt. De forma predeterminada está establecido en 3 durante la ejecución del script, correspondiente a Ctrl-C. Pasar -1 a esta función desactivará la captura de Ctrl-C, y pasar 3 la restaurará.

Esta función puede usarse para evitar la captura de Ctrl-C en el flujo entrante de caracteres que normalmente se usa para el REPL, en caso de que ese flujo se utilice para otros fines.

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

Programa la función func para que se ejecute «muy pronto». A la función se le pasa el valor arg como su único argumento. «Muy pronto» significa que el entorno de ejecución de MicroPython hará todo lo posible por ejecutar la función lo antes posible, dado que también intenta ser eficiente y que se cumplen las siguientes condiciones:

  • Una función programada nunca interrumpirá (preempt) a otra función programada.

  • Las funciones programadas siempre se ejecutan «entre códigos de operación», lo que significa que todas las operaciones fundamentales de Python (como añadir a una lista) tienen garantizada su atomicidad.

  • Un puerto determinado puede definir «regiones críticas» dentro de las cuales nunca se ejecutarán funciones programadas. Las funciones pueden programarse dentro de una región crítica, pero no se ejecutarán hasta que se salga de esa región. Un ejemplo de región crítica es un manejador de interrupciones con prioridad (una IRQ).

  • Dentro de las funciones de código nativo, las funciones programadas no se llaman a menos que el código nativo llame a una función que lo haga específicamente.

  • Ciertas funciones, incluidas poll.poll, poll.ipoll, time.sleep y time.sleep_ms (incluidos los sueños de duración cero), llamarán a las funciones programadas.

Un uso de esta función es programar una función de retorno (callback) desde una IRQ con prioridad. Tal IRQ impone restricciones sobre el código que se ejecuta en ella (por ejemplo, el montón puede estar bloqueado) y programar una función para llamarla más tarde levantará esas restricciones.

En puertos con múltiples hilos, el comportamiento de la función programada depende de si el Bloqueo Global del Intérprete (GIL) está habilitado para el puerto específico:

  • Si el GIL está habilitado, la función puede interrumpir cualquier hilo y ejecutarse en su contexto.

  • Si el GIL está deshabilitado, la función solo interrumpirá el hilo principal y se ejecutará en su contexto.

Nota: Si se llama a schedule() desde una IRQ con prioridad, cuando no se permite la asignación de memoria y la función de retorno (callback) que se pasará a schedule() es un método ligado (bound method), pasarlo directamente fallará. Esto se debe a que crear una referencia a un método ligado provoca una asignación de memoria. Una solución es crear una referencia al método en el constructor de la clase y pasar esa referencia a schedule(). Esto se discute en detalle aquí documentación de referencia bajo «Creation of Python objects».

Existe una cola finita para almacenar las funciones programadas y schedule() lanzará un RuntimeError si la cola está llena.

Clases

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

Proporciona un búfer circular (ringbuffer) de tamaño fijo para bytes con una interfaz de flujo (stream). Puede considerarse una variante de cola FIFO de io.BytesIO. Las dos formas del constructor difieren únicamente en cómo se suministra el búfer de respaldo:

  • RingIO(size) reserva el búfer de respaldo internamente. El clásico algoritmo de búfer circular reserva un byte para el seguimiento, por lo que el búfer asignado es un byte mayor que size y la instancia puede contener los size bytes completos de datos. Por ejemplo, RingIO(16) asigna un búfer de 17 bytes y contiene 16 bytes de datos.

  • RingIO(buffer) usa el buffer suministrado en su lugar en vez de asignar uno. Como se reserva un byte para el seguimiento, la instancia puede contener len(buffer) - 1 bytes de datos. Por ejemplo, RingIO(bytearray(16)) contiene 15 bytes de datos.

Una instancia de RingIO es segura para IRQ/hilos cuando se usa para pasar datos en una sola dirección (por ejemplo, escrita desde una IRQ y leída desde una función que no es IRQ, o viceversa). Esto no se cumple si una sola instancia se escribe desde contextos IRQ y no IRQ a la vez, lo que a menudo causaría corrupción de datos.

any() int

Devuelve un entero que cuenta el número de caracteres que se pueden leer.

read(nbytes: int | None = None) bytes

Lee los caracteres disponibles. Esta es una función no bloqueante. Si se especifica nbytes, lee como máximo esa cantidad de bytes; de lo contrario, lee tantos datos como sea posible.

Valor de retorno: un objeto bytes que contiene los bytes leídos. Será un objeto bytes de longitud cero si no hay datos disponibles.

readline(nbytes: int | None = None) bytes

Lee una línea, terminada en un carácter de nueva línea o retorno si existe alguno en el búfer; de lo contrario, devuelve los bytes disponibles en el búfer. Si se especifica nbytes, lee como máximo esa cantidad de bytes.

Valor de retorno: un objeto bytes que contiene la línea leída.

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

Lee los bytes disponibles en el buf proporcionado. Si se especifica nbytes, lee como máximo esa cantidad de bytes. De lo contrario, lee como máximo len(buf) bytes.

Valor de retorno: recuento entero del número de bytes leídos en buf.

write(buf: bytes | bytearray | memoryview) int

Escritura no bloqueante de bytes desde buf en el búfer circular, limitada por el espacio disponible en el búfer circular.

Valor de retorno: recuento entero de bytes escritos.

close() None

Operación sin efecto (no-op) proporcionada como parte de la interfaz estándar stream. No tiene ningún efecto sobre los datos del búfer circular.