espflash — ESP32-ROM-Bootloader-Firmware-Flasher

Dieses Modul stellt eine minimale ESPFlash-Implementierung bereit, die über eine UART mit dem ESP32-ROM-Bootloader kommuniziert. Es ist für In-System-Updates der ESP32-Firmware auf Begleitmodulen gedacht (zum Beispiel das auf Arduino-Boards verwendete U-blox-NINA-W10-Modul) und ist kein Ersatz für das vollständige esptool-Dienstprogramm. Erweiterte Funktionen (Stub-Loader, andere ESP-Chips, Deflate, Secure Boot usw.) werden absichtlich nicht unterstützt.

Der Treiber schaltet RESET und GPIO0 um, um den ESP32 in den Download-Modus zu versetzen, und sendet anschließend SLIP-gerahmte Befehle, um die Flash-Größe auszulesen, die SPI-Schnittstelle zu konfigurieren, das Firmware-Image zu schreiben und es über eine MD5-Prüfsumme zu verifizieren.

Beispiel für das Arduino Nano RP2040 Connect (das einzige von OpenMV unterstützte Board, auf dem espflash derzeit eingefroren ist). Die Reset- und Boot-Strap-Pins des NINA-W102 sind RP2040 GPIO 3 bzw. GPIO 2, und das UART0 des NINA ist mit RP2040 UART1 verdrahtet (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)

Erzeugt ein ESPFlash-Objekt, das den ESP32-ROM-Bootloader ansteuert.

  • reset ist eine machine.Pin-Instanz, die mit der RESET-Leitung des ESP32 verbunden und als Ausgang konfiguriert ist.

  • gpio0 ist eine machine.Pin-Instanz, die mit der GPIO0-Leitung des ESP32 verbunden und als Ausgang konfiguriert ist.

  • uart ist eine machine.UART-Instanz, die mit den UART0-Pins des ESP32 verbunden ist. Sie muss mit 115200 Baud und einem von Null verschiedenen Lese-Timeout initialisiert sein.

  • log_enabled aktiviert die ausführliche Protokollierung der mit dem Bootloader ausgetauschten SLIP-Frames. Nur zum Debuggen nützlich.

Der Konstruktor versucht, hashlib zu importieren. Wenn hashlib.md5 verfügbar ist, wird die von ESPFlash.flash_verify_file() verwendete laufende MD5-Prüfsumme während des Schreibens automatisch berechnet.

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

Ändert die Baudrate des Bootloader-UART.

  • baudrate ist die neue Baudrate, auf die umgeschaltet werden soll. Wenn sie sich von der aktuell aktiven Baudrate unterscheidet, wird ein CHANGE_BAUDRATE-Befehl an den Bootloader gesendet, bevor die lokale UART neu konfiguriert wird.

  • timeout ist reserviert und wird derzeit nicht verwendet.

Hat keine Wirkung, wenn das zugrunde liegende UART-Objekt keine init()-Methode implementiert.

bootloader(retry: int = 6) bool

Steuert RESET und GPIO0 an, um in den ESP32-ROM-Download-Modus zu wechseln und sich mit dem Bootloader zu synchronisieren.

  • retry ist die Anzahl der Reset-/Sync-Versuche, bevor aufgegeben wird.

Gibt bei Erfolg True zurück, andernfalls wird eine Exception ausgelöst.

flash_read_size() int

Liest die JEDEC-ID des SPI-Flash aus und gibt die Flash-Größe in Bytes zurück.

Löst eine Exception aus, wenn die gemeldeten Größenbits außerhalb des erwarteten Bereichs 0x12-0x19 liegen.

flash_attach() None

Verbindet sich mit dem SPI-Flash. Muss einmal nach bootloader() und vor jeder Flash-Lese-/Schreiboperation aufgerufen werden.

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

Konfiguriert die Parameter des SPI-Flash.

  • flash_size ist die gesamte Flash-Größe in Bytes, typischerweise der von flash_read_size() zurückgegebene Wert.

Die Block-, Sektor- und Seitengrößen sind fest auf 64 KiB, 4 KiB bzw. 256 Bytes eingestellt.

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

Schreibt ein Firmware-Image ab Offset 0 in den Flash.

  • path ist der Dateisystempfad der zu flashenden Firmware-Binärdatei.

  • blksize ist die Größe in Bytes jedes an den Bootloader gesendeten Datenblocks. Muss ein Vielfaches der Sektorgröße sein.

Der letzte Block wird mit 0xFF auf eine volle blksize aufgefüllt. Wenn MD5-Unterstützung verfügbar ist, wird die laufende MD5-Prüfsumme während des Schreibens aktualisiert, sodass flash_verify_file() ohne Argumente aufgerufen werden kann.

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

Verifiziert den Inhalt des Flash anhand einer Firmware-Datei.

  • path ist der Dateisystempfad der Referenz-Firmware-Binärdatei; ihre Größe bestimmt die Anzahl der zu verifizierenden Bytes.

  • digest ist eine optionale vorberechnete, hex-codierte MD5-Prüfsumme der Datei. Wenn None, wird die während des letzten flash_write_file()-Aufrufs berechnete Prüfsumme verwendet.

  • offset ist der Flash-Offset in Bytes, an dem die Verifizierung beginnt.

Löst eine Exception aus, wenn keine Prüfsumme verfügbar ist oder wenn der Flash-Inhalt nicht mit der Referenzprüfsumme übereinstimmt.

reboot() None

Sendet einen FLASH_END-Befehl, der den ROM-Bootloader anweist, den ESP32 neu zu starten und die frisch geflashte Firmware auszuführen. Es wird keine Antwort gelesen.