micropython — acesso e controle dos internos do MicroPython¶
Funções¶
- micropython.const(expr: int) int¶
Usada para declarar que a expressão é uma constante, de modo que o compilador possa otimizá-la. O uso desta função deve ser feito da seguinte forma:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
Constantes declaradas dessa forma ainda são acessíveis como variáveis globais de fora do módulo em que são declaradas. Por outro lado, se uma constante começa com um sublinhado, então ela fica oculta, não fica disponível como variável global e não ocupa nenhuma memória durante a execução.
Esta função
consté reconhecida diretamente pelo parser do MicroPython e é fornecida como parte do módulomicropythonprincipalmente para que se possam escrever scripts que rodam tanto sob CPython quanto sob MicroPython, seguindo o padrão acima.
- micropython.opt_level(level: int | None = None) int | None¶
Se level for fornecido, então esta função define o nível de otimização para compilações subsequentes de scripts e retorna
None. Caso contrário, retorna o nível de otimização atual.O nível de otimização controla as seguintes funcionalidades de compilação:
Asserções: no nível 0 as instruções assert ficam habilitadas e são compiladas no bytecode; nos níveis 1 e superiores as asserções não são compiladas.
Variável embutida
__debug__: no nível 0 esta variável expande paraTrue; nos níveis 1 e superiores ela expande paraFalse.Números de linha do código-fonte: nos níveis 0, 1 e 2 os números de linha do código-fonte são armazenados junto com o bytecode, de modo que as exceções possam reportar o número da linha em que ocorreram; nos níveis 3 e superiores os números de linha não são armazenados.
O nível de otimização padrão é geralmente o nível 0.
- micropython.alloc_emergency_exception_buf(size: int) None¶
Aloca size bytes de RAM para o buffer de exceções de emergência (um bom tamanho é cerca de 100 bytes). O buffer é usado para criar exceções nos casos em que a alocação normal de RAM falharia (por exemplo, dentro de um handler de interrupção) e, portanto, fornece informações úteis de traceback nessas situações.
Uma boa maneira de usar esta função é colocá-la no início do seu script principal (por exemplo,
boot.pyoumain.py) e então o buffer de exceções de emergência ficará ativo para todo o código que vier depois.
- micropython.mem_info(verbose: Any | None = None) None¶
Imprime informações sobre a memória atualmente em uso. Se o argumento verbose for fornecido, então informações extras são impressas.
As informações impressas dependem da implementação, mas atualmente incluem a quantidade de pilha e heap em uso. No modo verboso, ela imprime todo o heap, indicando quais blocos estão em uso e quais estão livres.
- micropython.qstr_info(verbose: Any | None = None) None¶
Imprime informações sobre as strings atualmente internadas. Se o argumento verbose for fornecido, então informações extras são impressas.
As informações impressas dependem da implementação, mas atualmente incluem o número de strings internadas e a quantidade de RAM que elas usam. No modo verboso, ela imprime os nomes de todas as strings internadas em RAM.
- micropython.stack_use() int¶
Retorna um inteiro representando a quantidade atual de pilha em uso. O valor absoluto disso não é particularmente útil; em vez disso, ele deve ser usado para calcular diferenças de uso de pilha em diferentes pontos.
- micropython.heap_lock() None¶
Bloqueia o heap. Enquanto bloqueado, nenhuma alocação de memória pode ocorrer e um
MemoryErrorserá levantado se qualquer alocação de heap for tentada.Os bloqueios são aninhados: chamar
heap_lock()várias vezes aumenta a profundidade do bloqueio. O heap permanece bloqueado até queheap_unlock()tenha sido chamado o mesmo número de vezes.Se o REPL se tornar ativo com o heap bloqueado, então ele será forçosamente desbloqueado.
- micropython.heap_unlock() int¶
Decrementa a profundidade do bloqueio do heap em um e retorna a nova profundidade como um inteiro não negativo. Um valor de retorno
0significa que o heap não está mais bloqueado e as alocações são novamente permitidas.
- micropython.heap_locked() int¶
Retorna a profundidade atual do bloqueio do heap como um inteiro não negativo;
0significa que o heap não está bloqueado.Nota: esta função não está disponível na OpenMV Cam.
- micropython.kbd_intr(chr: int) None¶
Define o caractere que levantará uma exceção
KeyboardInterrupt. Por padrão, isso é definido como 3 durante a execução do script, correspondendo a Ctrl-C. Passar -1 para esta função desabilitará a captura de Ctrl-C, e passar 3 a restaurará.Esta função pode ser usada para impedir a captura de Ctrl-C no fluxo de caracteres de entrada que normalmente é usado para o REPL, caso esse fluxo seja usado para outros fins.
- micropython.schedule(func: Callable[[Any], Any], arg: Any) None¶
Agenda a função func para ser executada “muito em breve”. A função recebe o valor arg como seu único argumento. “Muito em breve” significa que o runtime do MicroPython fará o possível para executar a função o mais cedo possível, considerando que ele também está tentando ser eficiente e que as seguintes condições se aplicam:
Uma função agendada nunca interromperá outra função agendada.
Funções agendadas são sempre executadas “entre opcodes”, o que significa que todas as operações fundamentais do Python (como anexar a uma lista) têm a atomicidade garantida.
Uma determinada port pode definir “regiões críticas” dentro das quais funções agendadas nunca serão executadas. Funções podem ser agendadas dentro de uma região crítica, mas não serão executadas até que essa região seja deixada. Um exemplo de região crítica é um handler de interrupção que interrompe (uma IRQ).
Dentro de funções de código nativo, funções agendadas não são chamadas a menos que o código nativo chame uma função que faça isso especificamente.
Certas funções, incluindo
poll.poll,poll.ipoll,time.sleepetime.sleep_ms(incluindo sleeps de duração zero), chamarão funções agendadas.
Um uso para esta função é agendar um callback a partir de uma IRQ que interrompe. Tal IRQ impõe restrições ao código que roda na IRQ (por exemplo, o heap pode estar bloqueado) e agendar uma função para chamar mais tarde levantará essas restrições.
Em ports multithread, o comportamento da função agendada depende de o Global Interpreter Lock (GIL) estar habilitado ou não para a port específica:
Se o GIL estiver habilitado, a função pode interromper qualquer thread e rodar em seu contexto.
Se o GIL estiver desabilitado, a função só interromperá a thread principal e rodará em seu contexto.
Nota: Se
schedule()for chamada a partir de uma IRQ que interrompe, quando a alocação de memória não é permitida e o callback a ser passado paraschedule()é um método vinculado, passá-lo diretamente falhará. Isso ocorre porque criar uma referência a um método vinculado causa alocação de memória. Uma solução é criar uma referência ao método no construtor da classe e passar essa referência paraschedule(). Isso é discutido em detalhes aqui documentação de referência, em “Creation of Python objects”.Há uma fila finita para conter as funções agendadas, e
schedule()levantará umRuntimeErrorse a fila estiver cheia.
Classes¶
- class micropython.RingIO(size: int)¶
- class micropython.RingIO(buffer: bytes | bytearray | memoryview)
Fornece um ringbuffer de tamanho fixo para bytes com uma interface de stream. Pode ser considerado uma variante de fila FIFO de
io.BytesIO. As duas formas do construtor diferem apenas em como o buffer de apoio é fornecido:RingIO(size)aloca o buffer de apoio internamente. O algoritmo clássico de ringbuffer reserva um byte para rastreamento, então o buffer alocado é um byte maior quesizee a instância pode conter ossizebytes completos de dados. Por exemplo,RingIO(16)aloca um buffer de 17 bytes e contém 16 bytes de dados.RingIO(buffer)usa obufferfornecido no lugar, em vez de alocar um. Como um byte é reservado para rastreamento, a instância pode conterlen(buffer) - 1bytes de dados. Por exemplo,RingIO(bytearray(16))contém 15 bytes de dados.
Uma instância de RingIO é segura para IRQ/thread quando usada para passar dados em uma única direção (por exemplo, escrita a partir de uma IRQ e lida a partir de uma função não-IRQ, ou vice-versa). Isso não vale se uma única instância for escrita tanto de contextos IRQ quanto não-IRQ, o que frequentemente causaria corrupção de dados.
- read(nbytes: int | None = None) bytes¶
Lê os caracteres disponíveis. Esta é uma função não bloqueante. Se
nbytesfor especificado, então lê no máximo essa quantidade de bytes; caso contrário, lê o máximo de dados possível.Valor de retorno: um objeto bytes contendo os bytes lidos. Será um objeto bytes de comprimento zero se nenhum dado estiver disponível.
- readline(nbytes: int | None = None) bytes¶
Lê uma linha, terminando em um caractere de nova linha ou retorno se houver um no buffer, ou então retorna os bytes disponíveis no buffer. Se
nbytesfor especificado, então lê no máximo essa quantidade de bytes.Valor de retorno: um objeto bytes contendo a linha lida.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Lê os bytes disponíveis para o
buffornecido. Senbytesfor especificado, então lê no máximo essa quantidade de bytes. Caso contrário, lê no máximolen(buf)bytes.Valor de retorno: contagem inteira do número de bytes lidos para
buf.
- write(buf: bytes | bytearray | memoryview) int¶
Escrita não bloqueante de bytes de
bufpara o ringbuffer, limitada pelo espaço disponível no ringbuffer.Valor de retorno: contagem inteira de bytes escritos.