espflash — ESP32 ROM 부트로더 펌웨어 플래셔

이 모듈은 UART를 통해 ESP32 ROM 부트로더와 통신하는 최소한의 ESPFlash 구현을 제공합니다. 이는 보조 모듈(예: Arduino 보드에서 사용되는 U-blox NINA-W10 모듈)의 ESP32 펌웨어를 시스템 내에서 업데이트하기 위한 것으로, 전체 esptool 유틸리티를 대체하는 것이 아닙니다. 고급 기능(스텁 로더, 기타 ESP 칩, deflate, 시큐어 부트 등)은 의도적으로 지원하지 않습니다.

이 드라이버는 RESETGPIO0을 토글하여 ESP32를 다운로드 모드로 전환한 다음, SLIP 프레임 명령을 발행하여 플래시 크기를 읽고, SPI 인터페이스를 구성하며, 펌웨어 이미지를 기록하고 MD5 다이제스트로 이를 검증합니다.

Arduino Nano RP2040 Connect(현재 espflash가 프리징되어 있는 유일한 OpenMV 지원 보드)에 대한 예제입니다. NINA-W102의 리셋 및 부트 스트랩 핀은 각각 RP2040 GPIO 3GPIO 2이며, NINA의 UART0은 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)

ESP32 ROM 부트로더를 구동하는 ESPFlash 객체를 생성합니다.

  • reset는 ESP32 RESET 라인에 연결되어 출력으로 구성된 machine.Pin 인스턴스입니다.

  • gpio0는 ESP32 GPIO0 라인에 연결되어 출력으로 구성된 machine.Pin 인스턴스입니다.

  • uart는 ESP32 UART0 핀에 연결된 machine.UART 인스턴스입니다. 0이 아닌 읽기 타임아웃을 사용하여 115200 보드 레이트로 초기화되어야 합니다.

  • log_enabled는 부트로더와 교환되는 SLIP 프레임의 상세 로깅을 활성화합니다. 디버깅 용도로만 유용합니다.

생성자는 hashlib을 임포트하려고 시도합니다. hashlib.md5를 사용할 수 있으면 ESPFlash.flash_verify_file()에서 사용하는 실행 중 MD5 다이제스트가 기록 중에 자동으로 계산됩니다.

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

부트로더 UART 보드 레이트를 변경합니다.

  • baudrate는 전환할 새 보드 레이트입니다. 현재 활성화된 보드 레이트와 다른 경우, 로컬 UART가 재구성되기 전에 CHANGE_BAUDRATE 명령이 부트로더에 발행됩니다.

  • timeout은 예약되어 있으며 현재 사용되지 않습니다.

기반이 되는 UART 객체가 init() 메서드를 구현하지 않으면 아무런 효과가 없습니다.

bootloader(retry: int = 6) bool

RESETGPIO0을 구동하여 ESP32 ROM 다운로드 모드로 진입하고 부트로더와 동기화합니다.

  • retry는 포기하기 전 리셋/동기화 시도 횟수입니다.

성공 시 True를 반환하고, 그렇지 않으면 Exception을 발생시킵니다.

flash_read_size() int

SPI 플래시 JEDEC ID를 읽고 플래시 크기를 바이트 단위로 반환합니다.

보고된 크기 비트가 예상 범위인 0x12-0x19 밖에 있으면 Exception을 발생시킵니다.

flash_attach() None

SPI 플래시에 연결합니다. bootloader() 이후 및 플래시 읽기/쓰기 작업 이전에 한 번 호출되어야 합니다.

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

SPI 플래시 매개변수를 구성합니다.

  • flash_size는 총 플래시 크기(바이트 단위)로, 일반적으로 flash_read_size()가 반환하는 값입니다.

블록, 섹터, 페이지 크기는 각각 64 KiB, 4 KiB, 256 바이트로 고정되어 있습니다.

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

오프셋 0에서 시작하여 펌웨어 이미지를 플래시에 기록합니다.

  • path는 플래시할 펌웨어 바이너리의 파일시스템 경로입니다.

  • blksize는 부트로더로 전송되는 각 데이터 블록의 크기(바이트 단위)입니다. 섹터 크기의 배수여야 합니다.

마지막 블록은 0xFF로 패딩되어 전체 blksize를 채웁니다. MD5 지원을 사용할 수 있으면 기록 중에 실행 중 MD5 다이제스트가 업데이트되어 flash_verify_file()을 인수 없이 호출할 수 있습니다.

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

플래시 내용을 펌웨어 파일과 비교하여 검증합니다.

  • path는 참조 펌웨어 바이너리의 파일시스템 경로입니다. 그 크기에 따라 검증할 바이트 수가 결정됩니다.

  • digest는 파일의 사전 계산된 16진수 인코딩 MD5 다이제스트(선택 사항)입니다. None이면 가장 최근의 flash_write_file() 호출 중에 계산된 다이제스트가 사용됩니다.

  • offset은 검증이 시작되는 플래시 오프셋(바이트 단위)입니다.

사용 가능한 다이제스트가 없거나 플래시 내용이 참조 다이제스트와 일치하지 않으면 Exception을 발생시킵니다.

reboot() None

ROM 부트로더에 ESP32를 재부팅하고 갓 플래시된 펌웨어를 실행하도록 지시하는 FLASH_END 명령을 전송합니다. 응답은 읽지 않습니다.