diff options
| author | Alex Evans <715855+mmalex@users.noreply.github.com> | 2024-11-07 12:01:15 +0000 |
|---|---|---|
| committer | Alex Evans <715855+mmalex@users.noreply.github.com> | 2024-11-07 12:01:15 +0000 |
| commit | cc7afbbb54d2b66cc3a89f2748c85fc632634d1f (patch) | |
| tree | 5f5c07c1aa0c6a9cf8dcf3543e68fd4626a8769f | |
| parent | 78a4df6ca67f937cda8462d43cbd9547994b6474 (diff) | |
| download | plinky-cc7afbbb54d2b66cc3a89f2748c85fc632634d1f.tar.gz | |
work on build tooling to choose a golden bootloader (dubbed, v1.04) and then make a BOOTLOAD.UF2 that actually encompasses latest firmware and the golden bootloader
| -rw-r--r-- | BOOTLOAD.UF2 | bin | 0 -> 1007616 bytes | |||
| -rw-r--r-- | binmaker.py | 62 | ||||
| -rw-r--r-- | boot0A7.uf2 | bin | 131072 -> 0 bytes | |||
| -rw-r--r-- | bootloader/.clang-format | 5 | ||||
| -rwxr-xr-x | bootloader/.settings/stm32cubeide.project.prefs | 4 | ||||
| -rwxr-xr-x | bootloader/Core/Src/ghostfat.c | 10 | ||||
| -rwxr-xr-x | bootloader/STM32L476VGTX_FLASH.ld | 8 | ||||
| -rw-r--r-- | golden_bootloader.bin | bin | 0 -> 31032 bytes | |||
| -rw-r--r-- | plink0A7.bin | bin | 1048576 -> 1046528 bytes | |||
| -rw-r--r-- | plink0A7.uf2 | bin | 876032 -> 876544 bytes | |||
| -rw-r--r-- | sw/.clang-format | 5 | ||||
| -rwxr-xr-x | sw/Core/Src/config.h | 5 | ||||
| -rwxr-xr-x | sw/Core/Src/plinky.c | 27 | ||||
| -rwxr-xr-x | sw/Core/Src/webusb.h | 1 |
14 files changed, 98 insertions, 29 deletions
diff --git a/BOOTLOAD.UF2 b/BOOTLOAD.UF2 Binary files differnew file mode 100644 index 0000000..f5080b1 --- /dev/null +++ b/BOOTLOAD.UF2 diff --git a/binmaker.py b/binmaker.py index c48e572..11f3c3a 100644 --- a/binmaker.py +++ b/binmaker.py @@ -1,10 +1,19 @@ +# this script takes the compiled firmware (sw/Release/plinkyblack.bin) and +# bundles it with a bootloader (golden_bootloader.bin) into a single binary file +# with a version number and filename extracted from the firmware. +# it USED to read the bootloader from (bootloader/Release/plinkybl.bin) but +# to avoid unnecessary flashing, it now reads the bootloader from the copy. +# if you want to update the bootloader, you need to copy it over the golden_bootloader.bin +# and rerun this script with the magic argument 'bootloader' + def main(): # bin file maker ver1 = '0' ver2 = '0' ver3 = '0' + bootloader_file = 'golden_bootloader.bin' # "bootloader/Release/plinkybl.bin" try: - with open("bootloader/Release/plinkybl.bin", "rb") as f1: + with open(bootloader_file, "rb") as f1: bl_content = f1.read() with open("sw/Release/plinkyblack.bin", "rb") as f2: app_content = f2.read() @@ -12,10 +21,16 @@ def main(): print(f"Failed to open file: {e}") exit(2) appsize = len(app_content) - print(f'{appsize} app, {len(bl_content)} bootloader') + bootloader_version = "0000" + if chr(bl_content[-3])=='.': + bootloader_version = chr(bl_content[-4]) + chr(bl_content[-3]) + chr(bl_content[-2]) + chr(bl_content[-1]) + print(f'SIZES: {appsize} app, {len(bl_content)} bootloader, bootloader version [{bootloader_version}]') # pad bl_content and app_content to reach their sizes - bl_content += b'\xff' * (65536 - len(bl_content)) - app_content += b'\xff' * (1024 * 1024 - 65536 - len(app_content)) + og_bl_size = len(bl_content) + bl_content += b'\xff' * (65536 - len(bl_content) - 4) + bl_content += bootloader_version.encode('ascii') + assert(len(bl_content) == 65536) + app_content += b'\xff' * (1024 * 1024 - 65536 - 2048 - len(app_content)) # leave the last sector empty for the calibration app = bl_content + app_content @@ -45,28 +60,33 @@ def main(): uf2args.convert=True uf2args.family='STM32L4' uf2args.input='sw/Release/plinkyblack.hex' - uf2args.base='0x2000' + uf2args.base='0x2000' # lol this is wrong, but luckily we were using .hex which has addresses. phew. + # the actual base address is 0x08010000 ie 64k into the flash. import uf2conv uf2conv.uf2conv(uf2args) - # read 'bootloader/Release/plinkybl.bin', pad to 64k, and write it back - try: - with open("bootloader/Release/plinkybl.bin", "rb") as f1: - bl_content = f1.read() - if len(bl_content) < 65536: - bl_content += b'\xff' * (65536 - len(bl_content)) - with open("bootloader/Release/plinkybl.bin", "wb") as f1: - f1.write(bl_content) - print('padded bootloader to 64k') - except IOError as e: - print(f"Failed to open file: {e}") - exit(2) - uf2args.input='bootloader/Release/plinkybl.bin' + with open("tempbl.bin", "wb") as f1: + f1.write(bl_content) + uf2args.input='tempbl.bin' uf2args.base='0x20008000' - uf2args.output=f"boot{ver1}{ver2}{ver3}.uf2" + uf2args.output=f"tempbl.uf2" uf2conv.uf2conv(uf2args) - - + # concatenate the two uf2 files tempbl.uf2 and fname + with open(f"BOOTLOAD.UF2", "wb") as f1: + with open("tempbl.uf2", "rb") as f2: + f1.write(f2.read()) + with open(fname, "rb") as f2: + f1.write(f2.read()) + # delete temp files + import os + os.remove("tempbl.bin") + os.remove("tempbl.uf2") + print("wrote a combiled firmware and bootloader package to BOOTLOAD.UF2") + checksum=0 + # interpret bl_content as a list of 32-bit words + for i in range(0, len(bl_content), 4): + checksum = (checksum * 23 + int.from_bytes(bl_content[i:i+4], 'little')) & 0xffffffff + print(f"bootloader checksum: 0x{checksum:08x} - this should be copied to GOLDEN_CHECKSUM in config.h") if __name__ == "__main__": main() diff --git a/boot0A7.uf2 b/boot0A7.uf2 Binary files differdeleted file mode 100644 index 8c8e9a2..0000000 --- a/boot0A7.uf2 +++ /dev/null diff --git a/bootloader/.clang-format b/bootloader/.clang-format new file mode 100644 index 0000000..025a880 --- /dev/null +++ b/bootloader/.clang-format @@ -0,0 +1,5 @@ +BasedOnStyle: LLVM +ColumnLimit: 132 +BreakBeforeBraces: Attach +SortIncludes: Never + diff --git a/bootloader/.settings/stm32cubeide.project.prefs b/bootloader/.settings/stm32cubeide.project.prefs index 8ed9ba8..c9a7670 100755 --- a/bootloader/.settings/stm32cubeide.project.prefs +++ b/bootloader/.settings/stm32cubeide.project.prefs @@ -1,4 +1,4 @@ -2F62501ED4689FB349E356AB974DBE57=94ADD5E4909A0CFA8C7645E0FE590B85 -8DF89ED150041C4CBC7CB9A9CAA90856=94ADD5E4909A0CFA8C7645E0FE590B85 +2F62501ED4689FB349E356AB974DBE57=AC0AF904BCE4C59D2BC8F5F3C8F9EA88 +8DF89ED150041C4CBC7CB9A9CAA90856=AC0AF904BCE4C59D2BC8F5F3C8F9EA88 DC22A860405A8BF2F2C095E5B6529F12=784C6BDED0B54E15528F5E4F1E9EDAE2 eclipse.preferences.version=1 diff --git a/bootloader/Core/Src/ghostfat.c b/bootloader/Core/Src/ghostfat.c index e3a94d6..28ff3e4 100755 --- a/bootloader/Core/Src/ghostfat.c +++ b/bootloader/Core/Src/ghostfat.c @@ -76,10 +76,14 @@ struct UF2File { int size; }; +#define BOOTLOADER_VERSION "1.04" +__attribute__((section(".signature"), used)) const char firmware_signature[4] = BOOTLOADER_VERSION; + + const char infoUf2File[] = // - "UF2 Bootloader v1.0.3 Plinky\r\n" - "Model: Plinky Synth v1.0.3\r\n" - "Board-ID: STM32L476-Plinky-103\r\n"; + "UF2 Bootloader v" BOOTLOADER_VERSION " Plinky\r\n" + "Model: Plinky Synth Bootloader v" BOOTLOADER_VERSION "\r\n" + "Board-ID: STM32L476-Plinky-v3\r\n"; const char indexFile[] = // "<!doctype html>\n" diff --git a/bootloader/STM32L476VGTX_FLASH.ld b/bootloader/STM32L476VGTX_FLASH.ld index e5b911a..e43d901 100755 --- a/bootloader/STM32L476VGTX_FLASH.ld +++ b/bootloader/STM32L476VGTX_FLASH.ld @@ -68,6 +68,7 @@ SECTIONS . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ + } >FLASH /* Constant data into "FLASH" Rom type memory */ @@ -122,6 +123,7 @@ SECTIONS . = ALIGN(4); } >FLASH + /* Used by the startup to initialize data */ _sidata = LOADADDR(.data); @@ -138,6 +140,7 @@ SECTIONS } >RAM AT> FLASH + /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : @@ -165,6 +168,11 @@ SECTIONS . = ALIGN(8); } >RAM + .signature : + { + . = ALIGN(4); + KEEP(*(.signature)) + } > FLASH /* Remove information from the compiler libraries */ /DISCARD/ : diff --git a/golden_bootloader.bin b/golden_bootloader.bin Binary files differnew file mode 100644 index 0000000..46c79c1 --- /dev/null +++ b/golden_bootloader.bin diff --git a/plink0A7.bin b/plink0A7.bin Binary files differindex 663936b..3061511 100644 --- a/plink0A7.bin +++ b/plink0A7.bin diff --git a/plink0A7.uf2 b/plink0A7.uf2 Binary files differindex 5658227..0b906b9 100644 --- a/plink0A7.uf2 +++ b/plink0A7.uf2 diff --git a/sw/.clang-format b/sw/.clang-format new file mode 100644 index 0000000..025a880 --- /dev/null +++ b/sw/.clang-format @@ -0,0 +1,5 @@ +BasedOnStyle: LLVM +ColumnLimit: 132 +BreakBeforeBraces: Attach +SortIncludes: Never + diff --git a/sw/Core/Src/config.h b/sw/Core/Src/config.h index 387382c..7cb83ab 100755 --- a/sw/Core/Src/config.h +++ b/sw/Core/Src/config.h @@ -59,3 +59,8 @@ // 0.A7 - Bootloader work to make it work on MacOSX #define VERSION2 "v0.A7" +// the bootloader is manually copied to the file golden_bootloader.bin +// makebin.py uses it to make a UF2 file containing the bootloader + latest firmware together +// it also checksums the firmware and prints out the value. it should match this value + +#define GOLDEN_CHECKSUM 0xb5a7228c
\ No newline at end of file diff --git a/sw/Core/Src/plinky.c b/sw/Core/Src/plinky.c index cdcec60..14ffafe 100755 --- a/sw/Core/Src/plinky.c +++ b/sw/Core/Src/plinky.c @@ -2557,6 +2557,7 @@ short *getrxbuf(void); #define REVERB_BUF 0x10000000 #define DELAY_BUF 0x20008000 + void check_bootloader_flash(void) { int count=0; uint32_t *rb32=(uint32_t*)REVERB_BUF; @@ -2569,8 +2570,23 @@ void check_bootloader_flash(void) { if (count!=64/4 || magic!=0xa738ea75) { return; } - clear(); char buf[32]; + // checksum! + uint32_t checksum = 0; + for (int i=0;i<65536/4;++i) { + checksum = checksum * 23 + ((uint32_t*)DELAY_BUF)[i]; + } + if (checksum != GOLDEN_CHECKSUM) { + DebugLog("bootloader checksum failed %08x != %08x\r\n", checksum, GOLDEN_CHECKSUM); + clear(); + drawstr(0,0,F_8,"bad bootloader crc"); + snprintf(buf, sizeof(buf), "%08x vs %08x", checksum, GOLDEN_CHECKSUM); + drawstr(0,8,F_8,buf); + oled_flip(vrambuf); + HAL_Delay(10000); + return; + } + clear(); snprintf(buf, sizeof(buf), "%08x %d", magic, count); drawstr(0, 0, F_16, buf); snprintf(buf, sizeof(buf), "%08x %08x", app_base[0], app_base[1]); @@ -2606,7 +2622,11 @@ void check_bootloader_flash(void) { } DebugLog("FLASHING BOOTLOADER! DO NOT RESET\r\n"); clear(); - drawstr(0,0,F_16_BOLD,"FLASHING\nBOOTLOADER"); + drawstr(0,0,F_12_BOLD,"FLASHING\nBOOTLOADER"); + char verbuf[5]={}; + memcpy(verbuf,(DELAY_BUF+65536-4),4); + drawstr(0,24,F_8,verbuf); + oled_flip(vrambuf); HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef EraseInitStruct; @@ -2640,7 +2660,8 @@ void check_bootloader_flash(void) { HAL_FLASH_Lock(); DebugLog("BOOTLOADER has been flashed!\r\n"); clear(); - drawstr(0,0,F_16_BOLD,"BOOTLOADER\nFLASHED OK!"); + drawstr(0,0,F_12_BOLD,"BOOTLOADER\nFLASHED OK!"); + drawstr(0,24,F_8,verbuf); oled_flip(vrambuf); HAL_Delay(3000); diff --git a/sw/Core/Src/webusb.h b/sw/Core/Src/webusb.h index 3405de5..495acd7 100755 --- a/sw/Core/Src/webusb.h +++ b/sw/Core/Src/webusb.h @@ -51,6 +51,7 @@ typedef struct WebUSBHeader { // 10 byte header u16 len; } WebUSBHeader; const static u8 wu_magic[4] = { 0xf3,0x0f,0xab,0xca }; // we expect magic to be these +const static u8 wu_magic_ext[4] = { 0xf4,0x1f,0xcb,0xdb }; // we expect magic to be these #define WEB_USB_TIMEOUT 500 enum { // state machine ticks thru these in order, more or less WU_MAGIC0, |
