espflash — gravador de firmware do bootloader ROM ESP32

Este módulo fornece uma implementação mínima de ESPFlash que comunica com o bootloader ROM do ESP32 via UART. Destina-se a atualizações in-system do firmware ESP32 em módulos complementares (por exemplo, o módulo U-blox NINA-W10 utilizado em placas Arduino), não sendo um substituto do utilitário completo esptool. Funcionalidades avançadas (stub loader, outros chips ESP, deflate, secure boot, etc.) não são suportadas intencionalmente.

O controlador alterna RESET e GPIO0 para colocar o ESP32 em modo de download, depois emite comandos em formato SLIP para ler o tamanho da flash, configurar a interface SPI, escrever a imagem de firmware e verificá-la através de um resumo MD5.

Exemplo para o Arduino Nano RP2040 Connect (a única placa suportada pelo OpenMV onde o espflash está atualmente congelado). Os pinos de reset e arranque do NINA-W102 são o GPIO 3 e o GPIO 2 do RP2040, respetivamente, e o UART0 do NINA está ligado ao UART1 do RP2040 (TX = GPIO 8, RX = GPIO 9):

from machine import Pin, UART
from espflash import ESPFlash

reset = Pin(3, Pin.OUT)                                    # NINA RESET
gpio0 = Pin(2, Pin.OUT)                                    # NINA GPIO0
uart = UART(1, 115200, timeout=1000)

esp = ESPFlash(reset, gpio0, uart)
esp.bootloader()
esp.set_baudrate(921600)
size = esp.flash_read_size()
esp.flash_attach()
esp.flash_config(size)
esp.flash_write_file("NINA_FW.bin")
esp.flash_verify_file("NINA_FW.bin")
esp.reboot()

class ESPFlash

class espflash.ESPFlash(reset: 'machine.Pin', gpio0: 'machine.Pin', uart: 'machine.UART', log_enabled: bool = False)

Constrói um objeto ESPFlash que controla o bootloader ROM do ESP32.

  • reset é uma instância de machine.Pin ligada à linha RESET do ESP32, configurada como saída.

  • gpio0 é uma instância de machine.Pin ligada à linha GPIO0 do ESP32, configurada como saída.

  • uart é uma instância de machine.UART ligada aos pinos UART0 do ESP32. Deve ser inicializada a 115200 baud com um timeout de leitura diferente de zero.

  • log_enabled ativa o registo detalhado dos frames SLIP trocados com o bootloader. Útil apenas para depuração.

O construtor tentará importar hashlib. Se hashlib.md5 estiver disponível, o resumo MD5 incremental utilizado por ESPFlash.flash_verify_file() será calculado automaticamente durante a escrita.

set_baudrate(baudrate: int, timeout: int = 350) None

Altera a taxa de baud do UART do bootloader.

  • baudrate é a nova taxa de baud para a qual comutar. Se for diferente da taxa de baud atualmente ativa, é emitido um comando CHANGE_BAUDRATE ao bootloader antes de o UART local ser reconfigurado.

  • timeout está reservado e não é utilizado atualmente.

Não tem efeito se o objeto UART subjacente não implementar um método init().

bootloader(retry: int = 6) bool

Aciona RESET e GPIO0 para entrar no modo de download ROM do ESP32 e sincronizar com o bootloader.

  • retry é o número de tentativas de reset/sincronização antes de desistir.

Devolve True em caso de sucesso; caso contrário, lança uma Exception.

flash_read_size() int

Lê o ID JEDEC da flash SPI e devolve o tamanho da flash em bytes.

Lança uma Exception se os bits de tamanho reportados estiverem fora do intervalo esperado 0x12-0x19.

flash_attach() None

Liga à flash SPI. Deve ser chamado uma vez após bootloader() e antes de qualquer operação de leitura/escrita na flash.

flash_config(flash_size: int = 2 * 1024 * 1024) None

Configura os parâmetros da flash SPI.

  • flash_size é o tamanho total da flash em bytes, tipicamente o valor devolvido por flash_read_size().

Os tamanhos de bloco, setor e página estão fixos em 64 KiB, 4 KiB e 256 bytes, respetivamente.

flash_write_file(path: str, blksize: int = 0x1000) None

Escreve uma imagem de firmware na flash a partir do offset 0.

  • path é o caminho no sistema de ficheiros do binário de firmware a gravar.

  • blksize é o tamanho em bytes de cada bloco de dados enviado ao bootloader. Deve ser múltiplo do tamanho do setor.

O último bloco é preenchido com 0xFF até ao blksize completo. Se o suporte a MD5 estiver disponível, o resumo MD5 incremental é atualizado durante a escrita para que flash_verify_file() possa ser chamado sem argumentos.

flash_verify_file(path: str, digest: bytes | None = None, offset: int = 0) None

Verifica o conteúdo da flash relativamente a um ficheiro de firmware.

  • path é o caminho no sistema de ficheiros do binário de firmware de referência; o seu tamanho determina o número de bytes a verificar.

  • digest é um resumo MD5 em hexadecimal pré-calculado do ficheiro, opcional. Se for None, é utilizado o resumo calculado durante a chamada mais recente a flash_write_file().

  • offset é o offset na flash em bytes a partir do qual a verificação começa.

Lança uma Exception se não houver resumo disponível ou se o conteúdo da flash não corresponder ao resumo de referência.

reboot() None

Envia um comando FLASH_END que instrui o bootloader ROM a reiniciar o ESP32 e executar o firmware recém-gravado. Nenhuma resposta é lida.