# Update Mboot or MicroPython from a .dfu.gz file on the board's filesystem # MIT license; Copyright (c) 2019-2022 Damien P. George from micropython import const import struct, time import deflate, machine, stm # Constants to be used with update_mpy VFS_FAT = 1 VFS_LFS1 = 2 VFS_LFS2 = 3 # Constants for creating mboot elements. _ELEM_TYPE_END = const(1) _ELEM_TYPE_MOUNT = const(2) _ELEM_TYPE_FSLOAD = const(3) _ELEM_TYPE_STATUS = const(4) def check_mem_contains(addr, buf): mem8 = stm.mem8 r = range(len(buf)) for off in r: if mem8[addr + off] != buf[off]: return False return True def dfu_read(filename): from binascii import crc32 f = open(filename, "rb") hdr = f.read(3) f.seek(0) if hdr == b"Dfu": pass elif hdr == b"\x1f\x8b\x08": f = deflate.DeflateIO(f, deflate.GZIP) else: print("Invalid firmware", filename) return None crc = 0 elems = [] hdr = f.read(11) crc = crc32(hdr, crc) sig, ver, size, num_targ = struct.unpack("<5sBIB", hdr) file_offset = 11 for i in range(num_targ): hdr = f.read(274) crc = crc32(hdr, crc) sig, alt, has_name, name, t_size, num_elem = struct.unpack("<6sBi255sII", hdr) file_offset += 274 file_offset_t = file_offset for j in range(num_elem): hdr = f.read(8) crc = crc32(hdr, crc) addr, e_size = struct.unpack(" flash.sector0_size: flash.erase_sector(1) flash.write(mboot_addr, mboot_fw) flash.lock() machine.enable_irq(irq) print("New Mboot programmed.") if check_mem_contains(mboot_addr, mboot_fw): print("Verification of new Mboot succeeded.") else: print("Verification of new Mboot FAILED! Try rerunning.") print("Programming finished, can now reset or turn off.") def _create_element(kind, body): return bytes([kind, len(body)]) + body def update_app_elements( filename, fs_base, fs_len, fs_type=VFS_FAT, fs_blocksize=0, status_addr=None, addr_64bit=False ): # Check firmware is of .dfu or .dfu.gz type try: with open(filename, "rb") as f: hdr = deflate.DeflateIO(f, deflate.GZIP).read(6) except Exception: with open(filename, "rb") as f: hdr = f.read(6) if hdr != b"DfuSe\x01": print("Firmware must be a .dfu(.gz) file.") return () if fs_type in (VFS_LFS1, VFS_LFS2) and not fs_blocksize: raise Exception("littlefs requires fs_blocksize parameter") mount_point = 1 mount_encoding = "