UPD: Concatenate update images into an update catalogue.

This means that we ship a single unified UPD file.
This commit is contained in:
Keir Fraser
2019-12-06 13:37:13 +00:00
parent 1159fba8ab
commit 6aaa2cf09b
3 changed files with 40 additions and 14 deletions

View File

@@ -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)" >$@

View File

@@ -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))

View File

@@ -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)