micropython — aceder e controlar os internos do MicroPython¶
Funções¶
- micropython.const(expr: int) int¶
Utilizado para declarar que a expressão é uma constante, de modo a que o compilador a possa otimizar. A utilização desta função deve ser a seguinte:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
As constantes declaradas desta forma ainda são acessíveis como variáveis globais a partir de fora do módulo em que são declaradas. Por outro lado, se uma constante começar com um sublinhado, está oculta, não está disponível como variável global e não ocupa qualquer 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 os scripts possam ser escritos de forma a correr tanto no CPython como no MicroPython, seguindo o padrão acima.
- micropython.opt_level(level: int | None = None) int | None¶
Se level for fornecido, esta função define o nível de otimização para a compilação subsequente 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: ao nível 0, as instruções de asserção estão ativas e são compiladas para bytecode; nos níveis 1 e superiores, as asserções não são compiladas.
Variável integrada
__debug__: ao nível 0, esta variável expande paraTrue; nos níveis 1 e superiores, 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 juntamente com o bytecode para que as exceções possam indicar o número de 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 é normalmente o nível 0.
- micropython.alloc_emergency_exception_buf(size: int) None¶
Aloca size bytes de RAM para o buffer de exceção de emergência (um bom tamanho é cerca de 100 bytes). O buffer é utilizado 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 rastreamento nessas situações.
Uma boa forma de utilizar esta função é colocá-la no início do seu script principal (por exemplo,
boot.pyoumain.py) e assim o buffer de exceção de emergência estará ativo para todo o código que se segue.
- micropython.mem_info(verbose: Any | None = None) None¶
Imprime informações sobre a memória atualmente utilizada. Se o argumento verbose for fornecido, são impressas informações adicionais.
A informação impressa depende da implementação, mas atualmente inclui a quantidade de stack e heap utilizadas. No modo verbose, imprime toda a heap indicando quais os blocos que 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, são impressas informações adicionais.
A informação impressa depende da implementação, mas atualmente inclui o número de strings internadas e a quantidade de RAM que utilizam. No modo verbose, imprime os nomes de todas as strings internadas em RAM.
- micropython.stack_use() int¶
Retorna um inteiro que representa a quantidade atual de stack em uso. O valor absoluto não é particularmente útil; serve antes para calcular diferenças no uso da stack em diferentes pontos.
- micropython.heap_lock() None¶
Bloqueia a heap. Enquanto bloqueada, não pode ocorrer qualquer alocação de memória e será lançado um
MemoryErrorse for tentada qualquer alocação na heap.Os bloqueios são aninhados: chamar
heap_lock()várias vezes aumenta a profundidade do bloqueio. A heap permanece bloqueada até queheap_unlock()tenha sido chamado o mesmo número de vezes.Se o REPL ficar ativo com a heap bloqueada, esta será desbloqueada forçosamente.
- micropython.heap_unlock() int¶
Decrementa a profundidade do bloqueio da heap em um e retorna a nova profundidade como um inteiro não negativo. Um valor de retorno de
0significa que a heap já não está bloqueada e as alocações são novamente permitidas.
- micropython.heap_locked() int¶
Retorna a profundidade atual do bloqueio da heap como um inteiro não negativo;
0significa que a heap não está bloqueada.Nota: esta função não está disponível no OpenMV Cam.
- micropython.kbd_intr(chr: int) None¶
Define o caráter que irá lançar uma exceção
KeyboardInterrupt. Por padrão, este é definido como 3 durante a execução do script, correspondendo a Ctrl-C. Passar -1 a esta função desativa a captura de Ctrl-C, e passar 3 restaura-a.Esta função pode ser utilizada para impedir a captura de Ctrl-C no fluxo de caracteres de entrada que normalmente é utilizado para o REPL, caso esse fluxo seja utilizado 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 único argumento. «Muito em breve» significa que o runtime do MicroPython fará o seu melhor para executar a função o mais cedo possível, tendo em conta que também tenta ser eficiente, e que as seguintes condições se verificam:
Uma função agendada nunca irá preemptar outra função agendada.
As funções agendadas são sempre executadas «entre opcodes», o que significa que todas as operações fundamentais de Python (como adicionar a uma lista) têm a garantia de ser atómicas.
Uma determinada porta pode definir «regiões críticas» nas quais as funções agendadas nunca serão executadas. As funções podem ser agendadas dentro de uma região crítica, mas não serão executadas até que essa região seja abandonada. Um exemplo de região crítica é um handler de interrupção preemptivo (um IRQ).
Dentro de funções de código nativo, as funções agendadas não são chamadas, a menos que o código nativo chame uma função que especificamente o faça.
Certas funções, incluindo
poll.poll,poll.ipoll,time.sleepetime.sleep_ms(incluindo durações de zero), irão chamar as funções agendadas.
Uma utilização para esta função é agendar um callback a partir de um IRQ preemptivo. Tal IRQ impõe restrições ao código que corre no IRQ (por exemplo, a heap pode estar bloqueada) e agendar uma função para chamar mais tarde elimina essas restrições.
Em portas com múltiplas threads, o comportamento da função agendada depende de se o Global Interpreter Lock (GIL) está ativado para a porta específica:
Se o GIL estiver ativado, a função pode preemptar qualquer thread e correr no seu contexto.
Se o GIL estiver desativado, a função apenas irá preemptar a thread principal e correr no seu contexto.
Nota: Se
schedule()for chamada a partir de um IRQ preemptivo, quando a alocação de memória não é permitida e o callback a ser passado aschedule()é um método vinculado, passá-lo diretamente falhará. Isto deve-se ao facto de criar uma referência a um método vinculado causar alocação de memória. Uma solução é criar uma referência ao método no construtor da classe e passar essa referência aschedule(). Isto é discutido em detalhe aqui documentação de referência em «Creation of Python objects».Existe uma fila finita para guardar as funções agendadas e
schedule()lançará 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 FIFO de
io.BytesIO. As duas formas de construtor diferem apenas na forma como o buffer de suporte é fornecido:RingIO(size)aloca o buffer de suporte internamente. O algoritmo clássico de ringbuffer reserva um byte para rastreamento, pelo que o buffer alocado tem um byte a mais do quesizee a instância pode guardar ossizebytes completos de dados. Por exemplo,RingIO(16)aloca um buffer de 17 bytes e guarda 16 bytes de dados.RingIO(buffer)usa obufferfornecido no lugar em vez de alocar um. Uma vez que um byte é reservado para rastreamento, a instância pode guardarlen(buffer) - 1bytes de dados. Por exemplo,RingIO(bytearray(16))guarda 15 bytes de dados.
Uma instância de RingIO é segura para IRQ/threads quando utilizada para passar dados numa única direção (por exemplo, escrita a partir de um IRQ e leitura a partir de uma função não-IRQ, ou vice-versa). Isto não se verifica se uma única instância for escrita tanto a partir de contextos IRQ como não-IRQ, o que frequentemente causaria corrupção de dados.
- read(nbytes: int | None = None) bytes¶
Lê os carateres disponíveis. Esta é uma função não bloqueante. Se
nbytesfor especificado, 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 não houver dados disponíveis.
- readline(nbytes: int | None = None) bytes¶
Lê uma linha que termina num caráter de newline, ou retorna se existir uma no buffer; caso contrário, retorna os bytes disponíveis no buffer. Se
nbytesfor especificado, 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, 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.