espflash — nástroj pro nahrávání firmwaru přes ESP32 ROM bootloader

Tento modul poskytuje minimální implementaci ESPFlash, která komunikuje s ESP32 ROM bootloaderem přes UART. Je určen pro aktualizace firmwaru ESP32 přímo v systému na doprovodných modulech (například modul U-blox NINA-W10 používaný na deskách Arduino) a nenahrazuje plnohodnotný nástroj esptool. Pokročilé funkce (stub loader, jiné čipy ESP, deflate, secure boot atd.) záměrně nejsou podporovány.

Ovladač přepíná piny RESET a GPIO0, aby přepnul ESP32 do režimu stahování, a poté vydává příkazy v rámci SLIP pro čtení velikosti flash paměti, konfiguraci rozhraní SPI, zápis obrazu firmwaru a jeho ověření pomocí MD5 otisku.

Příklad pro Arduino Nano RP2040 Connect (jedinou deskou podporovanou OpenMV, kde je espflash aktuálně zamrznutý ve firmwaru). Reset a boot-strap piny modulu NINA-W102 jsou RP2040 GPIO 3 a GPIO 2, UART0 modulu NINA je připojen k RP2040 UART1 (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)

Vytvoří objekt ESPFlash, který řídí ESP32 ROM bootloader.

  • reset je instance machine.Pin připojená k lince RESET čipu ESP32, nakonfigurovaná jako výstup.

  • gpio0 je instance machine.Pin připojená k lince GPIO0 čipu ESP32, nakonfigurovaná jako výstup.

  • uart je instance machine.UART připojená k pinům UART0 čipu ESP32. Musí být inicializována na 115200 baud s nenulovým časovým limitem pro čtení.

  • log_enabled zapíná podrobné protokolování SLIP rámců vyměňovaných s bootloaderem. Užitečné pouze pro ladění.

Konstruktor se pokusí importovat hashlib. Pokud je hashlib.md5 k dispozici, průběžný MD5 otisk používaný metodou ESPFlash.flash_verify_file() se automaticky vypočítá během zápisu.

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

Změní přenosovou rychlost (baud rate) UART bootloaderu.

  • baudrate je nová přenosová rychlost, na kterou se má přepnout. Pokud se liší od aktuálně aktivní přenosové rychlosti, je bootloaderu před překonfigurováním lokálního UART vydán příkaz CHANGE_BAUDRATE.

  • timeout je rezervován a aktuálně se nepoužívá.

Nemá žádný účinek, pokud podkladový objekt UART neimplementuje metodu init().

bootloader(retry: int = 6) bool

Přepne RESET a GPIO0 pro vstup do režimu stahování ESP32 ROM a synchronizuje se s bootloaderem.

  • retry je počet pokusů o reset/synchronizaci před vzdáním.

Vrací True při úspěchu, jinak vyvolá Exception.

flash_read_size() int

Přečte JEDEC ID SPI flash paměti a vrátí velikost flash paměti v bajtech.

Vyvolá Exception, pokud jsou hlášené bity velikosti mimo očekávaný rozsah 0x12-0x19.

flash_attach() None

Připojí se k SPI flash paměti. Musí být zavoláno jednou po bootloader() a před jakoukoli operací čtení/zápisu flash paměti.

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

Nakonfiguruje parametry SPI flash paměti.

  • flash_size je celková velikost flash paměti v bajtech, obvykle hodnota vrácená metodou flash_read_size().

Velikosti bloku, sektoru a stránky jsou pevně nastaveny na 64 KiB, 4 KiB a 256 bajtů.

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

Zapíše obraz firmwaru do flash paměti počínaje offsetem 0.

  • path je cesta v souborovém systému k binárnímu souboru firmwaru, který se má nahrát.

  • blksize je velikost každého datového bloku odeslaného bootloaderu v bajtech. Musí být násobkem velikosti sektoru.

Poslední blok je doplněn hodnotou 0xFF do plné velikosti blksize. Pokud je k dispozici podpora MD5, průběžný MD5 otisk se během zápisu aktualizuje, takže metodu flash_verify_file() lze volat bez argumentů.

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

Ověří obsah flash paměti proti souboru s firmwarem.

  • path je cesta v souborovém systému k referenčnímu binárnímu souboru firmwaru; jeho velikost určuje počet bajtů, které se mají ověřit.

  • digest je volitelný předem vypočítaný MD5 otisk souboru zakódovaný v šestnáctkové soustavě. Pokud je None, použije se otisk vypočítaný během posledního volání flash_write_file().

  • offset je offset flash paměti v bajtech, na kterém ověření začíná.

Vyvolá Exception, pokud není k dispozici žádný otisk nebo pokud obsah flash paměti neodpovídá referenčnímu otisku.

reboot() None

Odešle příkaz FLASH_END, který instruuje ROM bootloader, aby restartoval ESP32 a spustil čerstvě nahraný firmware. Žádná odpověď se nečte.