espflash — Programador de firmware del bootloader ROM del ESP32

Este módulo proporciona una implementación mínima de ESPFlash que se comunica con el gestor de arranque (bootloader) ROM del ESP32 a través de un UART. Está pensado para actualizaciones en sistema del firmware del ESP32 en módulos acompañantes (por ejemplo, el módulo U-blox NINA-W10 usado en placas Arduino), y no sustituye a la utilidad completa esptool. Las funciones avanzadas (stub loader, otros chips ESP, deflate, arranque seguro, etc.) no se admiten de forma intencionada.

El controlador conmuta RESET y GPIO0 para poner el ESP32 en modo de descarga, y luego emite comandos con tramas SLIP para leer el tamaño de la memoria flash, configurar la interfaz SPI, escribir la imagen de firmware y verificarla mediante un resumen MD5.

Ejemplo para la Arduino Nano RP2040 Connect (la única placa compatible con OpenMV donde espflash está actualmente congelado). Los pines de reinicio y de arranque (boot-strap) del NINA-W102 son los GPIO 3 y GPIO 2 del RP2040 respectivamente, y el UART0 del NINA está conectado al UART1 del 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)

Construye un objeto ESPFlash que controla el bootloader ROM del ESP32.

  • reset es una instancia de machine.Pin conectada a la línea RESET del ESP32, configurada como salida.

  • gpio0 es una instancia de machine.Pin conectada a la línea GPIO0 del ESP32, configurada como salida.

  • uart es una instancia de machine.UART conectada a los pines UART0 del ESP32. Debe inicializarse a 115200 baudios con un tiempo de espera de lectura distinto de cero.

  • log_enabled habilita el registro detallado de las tramas SLIP intercambiadas con el bootloader. Útil solo para depuración.

El constructor intentará importar hashlib. Si hashlib.md5 está disponible, el resumen MD5 en curso que utiliza ESPFlash.flash_verify_file() se calculará automáticamente durante la escritura.

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

Cambia la velocidad en baudios del UART del bootloader.

  • baudrate es la nueva velocidad en baudios a la que cambiar. Si es distinta de la velocidad en baudios actualmente activa, se emite un comando CHANGE_BAUDRATE al bootloader antes de reconfigurar el UART local.

  • timeout está reservado y actualmente no se utiliza.

No tiene efecto si el objeto UART subyacente no implementa un método init().

bootloader(retry: int = 6) bool

Controla RESET y GPIO0 para entrar en el modo de descarga ROM del ESP32 y sincronizarse con el bootloader.

  • retry es el número de intentos de reinicio/sincronización antes de rendirse.

Devuelve True si tiene éxito; de lo contrario lanza una Exception.

flash_read_size() int

Lee el identificador JEDEC de la memoria flash SPI y devuelve el tamaño de la flash en bytes.

Lanza una Exception si los bits de tamaño reportados están fuera del rango esperado 0x12-0x19.

flash_attach() None

Se conecta a la memoria flash SPI. Debe llamarse una vez después de bootloader() y antes de cualquier operación de lectura/escritura de flash.

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

Configura los parámetros de la memoria flash SPI.

  • flash_size es el tamaño total de la flash en bytes, normalmente el valor devuelto por flash_read_size().

Los tamaños de bloque, sector y página están fijados en 64 KiB, 4 KiB y 256 bytes respectivamente.

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

Escribe una imagen de firmware en la memoria flash empezando en el desplazamiento 0.

  • path es la ruta del sistema de archivos del binario de firmware que se va a grabar.

  • blksize es el tamaño en bytes de cada bloque de datos enviado al bootloader. Debe ser un múltiplo del tamaño de sector.

El último bloque se rellena con 0xFF hasta completar un blksize completo. Si hay soporte de MD5 disponible, el resumen MD5 en curso se actualiza durante la escritura para que flash_verify_file() pueda llamarse sin argumentos.

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

Verifica el contenido de la memoria flash comparándolo con un archivo de firmware.

  • path es la ruta del sistema de archivos del binario de firmware de referencia; su tamaño determina el número de bytes a verificar.

  • digest es un resumen MD5 opcional precalculado y codificado en hexadecimal del archivo. Si es None, se utiliza el resumen calculado durante la llamada más reciente a flash_write_file().

  • offset es el desplazamiento de la flash en bytes en el que comienza la verificación.

Lanza una Exception si no hay ningún resumen disponible o si el contenido de la flash no coincide con el resumen de referencia.

reboot() None

Envía un comando FLASH_END que indica al bootloader ROM que reinicie el ESP32 y ejecute el firmware recién grabado. No se lee ninguna respuesta.