Browse Source

UPD: Concatenate update images into an update catalogue.
This means that we ship a single unified UPD file.

Keir Fraser 5 years ago
parent
commit
6aaa2cf09b
3 changed files with 40 additions and 14 deletions
  1. 3 3
      Makefile
  2. 20 3
      scripts/greaseweazle/tools/update.py
  3. 17 8
      scripts/mk_update.py

+ 3 - 3
Makefile

@@ -29,7 +29,7 @@ dist:
 	$(MAKE) clean
 	stm32=f1 $(MAKE) all blinky
 	cp -a $(PROJ)-$(VER).hex $(PROJ)-$(VER)/$(PROJ)-F1-$(VER).hex
-	cp -a $(PROJ)-$(VER).upd $(PROJ)-$(VER)/$(PROJ)-F1-$(VER).upd
+	cp -a $(PROJ)-$(VER).upd $(PROJ)-$(VER)/$(PROJ)-$(VER).upd
 	cp -a blinky_test/Blinky.hex $(PROJ)-$(VER)/alt/Blinky_Test-$(VER).hex
 	cp -a COPYING $(PROJ)-$(VER)/
 	cp -a README.md $(PROJ)-$(VER)/
@@ -45,7 +45,7 @@ dist:
 	$(MAKE) clean
 	stm32=f7 $(MAKE) all
 	cp -a $(PROJ)-$(VER).hex $(PROJ)-$(VER)/$(PROJ)-F7-$(VER).hex
-	cp -a $(PROJ)-$(VER).upd $(PROJ)-$(VER)/$(PROJ)-F7-$(VER).upd
+	cat $(PROJ)-$(VER).upd >>$(PROJ)-$(VER)/$(PROJ)-$(VER).upd
 	$(MAKE) clean
 	zip -r $(PROJ)-$(VER).zip $(PROJ)-$(VER)
 
@@ -64,7 +64,7 @@ all: scripts/greaseweazle/version.py
 		Bootloader.elf Bootloader.bin Bootloader.hex
 	srec_cat bootloader/Bootloader.hex -Intel src/$(PROJ).hex -Intel \
 	-o $(PROJ)-$(VER).hex -Intel
-	$(PYTHON) ./scripts/mk_update.py src/$(PROJ).bin $(PROJ)-$(VER).upd
+	$(PYTHON) ./scripts/mk_update.py src/$(PROJ).bin $(PROJ)-$(VER).upd $(stm32)
 
 scripts/greaseweazle/version.py: Makefile
 	echo "major = $(FW_MAJOR)" >$@

+ 20 - 3
scripts/greaseweazle/tools/update.py

@@ -17,17 +17,34 @@ from greaseweazle import usb as USB
 # Updates the Greaseweazle firmware using the specified Update File.
 def update_firmware(usb, args):
 
-    # Read and check the update file.
+    # Read the entire update catalogue.
     with open(args.file, "rb") as f:
         dat = f.read()
-    sig, maj, min, pad1, pad2, crc = struct.unpack(">2s4BH", dat[-8:])
-    if len(dat) & 3 != 0 or sig != b'GW' or pad1 != 0 or pad2 != 0:
+
+    # Search the catalogue for a match on our Weazle's hardware type.
+    while dat:
+        upd_len, hw_type = struct.unpack("<2H", dat[:4])
+        if hw_type == usb.hw_type:
+            # Match: Pull out the embedded update file.
+            dat = dat[4:upd_len+4]
+            break
+        # Skip to the next catalogue entry.
+        dat = dat[upd_len+4:]
+
+    if not dat:
+        print("%s: No match for hardware type %x" % (args.file, usb.hw_type))
+        return
+
+    # Check the matching update file's footer.
+    sig, maj, min, hw_type = struct.unpack("<2s2BH", dat[-8:-2])
+    if len(dat) & 3 != 0 or sig != b'GW' or hw_type != usb.hw_type:
         print("%s: Bad update file" % (args.file))
         return
     crc16 = crcmod.predefined.Crc('crc-ccitt-false')
     crc16.update(dat)
     if crc16.crcValue != 0:
         print("%s: Bad CRC" % (args.file))
+        return
 
     # Perform the update.
     print("Updating to v%u.%u..." % (maj, min))

+ 17 - 8
scripts/mk_update.py

@@ -1,11 +1,18 @@
 # mk_update.py
 #
-# Convert a raw firmware binary into an update file for our bootloader:
-#  N bytes: <raw binary data>
-#  2 bytes: 'GW'
-#  2 bytes: major, minor
-#  2 bytes: 0, 0
-#  2 bytes: CRC16-CCITT, seed 0xFFFF, stored big endian
+# Convert a raw firmware binary into an update file for our bootloader.
+#
+# Update Format (Little endian, unless otherwise stated):
+#   Catalogue Header:
+#     2 bytes: <length> (excludes Catalogue Header)
+#     2 bytes: <hw_type>
+#   Payload:
+#     N bytes: <raw binary data>
+#   Footer:
+#     2 bytes: 'GW'
+#     2 bytes: major, minor
+#     2 bytes: <hw_type>
+#     2 bytes: CRC16-CCITT, seed 0xFFFF (big endian, excludes Catalogue Header)
 #
 # Written & released by Keir Fraser <keir.xen@gmail.com>
 #
@@ -13,20 +20,22 @@
 # See the file COPYING for more details, or visit <http://unlicense.org>.
 
 import crcmod.predefined
-import struct, sys
+import re, struct, sys
 
 from greaseweazle import version
 
 def main(argv):
     in_f = open(argv[1], "rb")
     out_f = open(argv[2], "wb")
+    hw_type = int(re.match("f(\d)", argv[3]).group(1))
     in_dat = in_f.read()
     in_len = len(in_dat)
     assert (in_len & 3) == 0, "input is not longword padded"
     crc16 = crcmod.predefined.Crc('crc-ccitt-false')
+    out_f.write(struct.pack("<2H", in_len + 8, hw_type))
     out_f.write(in_dat)
     crc16.update(in_dat)
-    in_dat = struct.pack("2s4B", b'GW', version.major, version.minor, 0, 0)
+    in_dat = struct.pack("<2s2BH", b'GW', version.major, version.minor, hw_type)
     out_f.write(in_dat)
     crc16.update(in_dat)
     in_dat = struct.pack(">H", crc16.crcValue)