2222from .ble .lwp3 .bootloader import BootloaderCommand
2323from .ble .lwp3 .bytecodes import HubKind
2424from .compile import compile_file , save_script
25+ from .firmware import ExtendedFirmwareMetadata , AnyFirmwareMetadata
2526from .tools .checksum import crc32_checksum , sum_complement
2627
2728logger = logging .getLogger (__name__ )
2829
2930
3031async def create_firmware (
3132 firmware_zip : Union [str , os .PathLike , BinaryIO ], name : Optional [str ] = None
32- ) -> Tuple [bytes , dict ]:
33+ ) -> Tuple [bytes , ExtendedFirmwareMetadata ]:
3334 """Creates a firmware blob from base firmware and main.mpy file.
3435
3536 Arguments:
@@ -39,8 +40,8 @@ async def create_firmware(
3940 A custom name for the hub.
4041
4142 Returns:
42- bytes: Composite binary blob with correct padding and checksum.
43- dict: Meta data for this firmware file.
43+ Composite binary blob with correct padding and checksum and
44+ extended metadata for this firmware file.
4445
4546 Raises:
4647 ValueError:
@@ -50,34 +51,31 @@ async def create_firmware(
5051 """
5152
5253 archive = zipfile .ZipFile (firmware_zip )
53- metadata = json .load (archive .open ("firmware.metadata.json" ))
54+ metadata : AnyFirmwareMetadata = json .load (archive .open ("firmware.metadata.json" ))
5455
55- # Check if there's a complete firmware already
56- if "firmware.bin" in archive .namelist ():
57- # If so, use it as-is, with the final checksum stripped off.
58- # We'll add an updated checksum later on.
59- firmware = bytearray (archive .open ("firmware.bin" ).read ()[:- 4 ])
60- else :
61- # Otherwise, we have to take a base firmware and extend it.
62- base = archive .open ("firmware-base.bin" ).read ()
56+ base = archive .open ("firmware-base.bin" ).read ()
57+
58+ if "main.py" in archive .namelist ():
6359 main_py = io .TextIOWrapper (archive .open ("main.py" ))
6460
6561 mpy = await compile_file (
6662 save_script (main_py .read ()),
6763 metadata ["mpy-cross-options" ],
6864 metadata ["mpy-abi-version" ],
6965 )
70-
71- # start with base firmware binary blob
72- firmware = bytearray (base )
73- # pad with 0s until user-mpy-offset
74- firmware .extend (0 for _ in range (metadata ["user-mpy-offset" ] - len (firmware )))
75- # append 32-bit little-endian main.mpy file size
76- firmware .extend (struct .pack ("<I" , len (mpy )))
77- # append main.mpy file
78- firmware .extend (mpy )
79- # pad with 0s to align to 4-byte boundary
80- firmware .extend (0 for _ in range (- len (firmware ) % 4 ))
66+ else :
67+ mpy = b""
68+
69+ # start with base firmware binary blob
70+ firmware = bytearray (base )
71+ # pad with 0s until user-mpy-offset
72+ firmware .extend (0 for _ in range (metadata ["user-mpy-offset" ] - len (firmware )))
73+ # append 32-bit little-endian main.mpy file size
74+ firmware .extend (struct .pack ("<I" , len (mpy )))
75+ # append main.mpy file
76+ firmware .extend (mpy )
77+ # pad with 0s to align to 4-byte boundary
78+ firmware .extend (0 for _ in range (- len (firmware ) % 4 ))
8179
8280 # Update hub name if given
8381 if name :
@@ -110,7 +108,7 @@ async def create_firmware(
110108 # Append checksum to the firmware
111109 firmware .extend (struct .pack ("<I" , checksum ))
112110
113- # Update sha256 of updated composite firmware
111+ # Add extended metadata needed by install_pybricks.py
114112 metadata ["firmware-sha256" ] = hashlib .sha256 (firmware ).hexdigest ()
115113
116114 return firmware , metadata
0 commit comments