Skip to content

Commit

Permalink
support bootloader update with CAN bootloader
Browse files Browse the repository at this point in the history
  • Loading branch information
tridge committed Nov 9, 2024
1 parent 30abefd commit 84b3a07
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 4 deletions.
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ $(ELF_FILE): $$(SRC_$(MCU)_BL) $$(SRC_BL) $$(SRC_DRONECAN)
$(H_FILE): $(BIN_FILE)
$$(QUIET)python3 bl_update/make_binheader.py $(BIN_FILE) $(H_FILE)

$(BLU_ELF_FILE): CFLAGS_BLU := $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) -DBOOTLOADER -DUSE_$(PIN) $(EXTRA_CFLAGS) -Wno-unused-variable -Wno-unused-function
$(BLU_ELF_FILE): CFLAGS_BLU := -DAM32_MCU=\"$(MCU)\" $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) -DBOOTLOADER -DUSE_$(PIN) $(EXTRA_CFLAGS) -Wno-unused-variable -Wno-unused-function
$(BLU_ELF_FILE): LDFLAGS_BLU := $$(LDFLAGS_COMMON) $$(LDFLAGS_$(MCU)) -T$(xBLU_LDSCRIPT)
$(BLU_ELF_FILE): $$(SRC_$(MCU)_BL) $$(SRC_BLU) $(H_FILE)
$$(QUIET)echo building bootloader updater for $(BUILD) with pin $(PIN)
Expand All @@ -191,12 +191,13 @@ $(HEX_FILE): $$(ELF_FILE)
$(BIN_FILE): $$(HEX_FILE)

# Generate bin and hex files for bl updater
$(BLU_HEX_FILE): $$(BLU_ELF_FILE)
$(BLU_BIN_FILE): $$(BLU_ELF_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)$(xOBJCOPY) -O binary $$(<) $$(@:.hex=.bin)
$$(QUIET)python3 bl_update/set_app_signature.py $$@ $$(<)
$$(QUIET)$(xOBJCOPY) $$(<) -O ihex $$(@:.bin=.hex)

$(BLU_AMJ_FILE): $$(BLU_HEX_FILE)
$(BLU_AMJ_FILE): $$(BLU_BIN_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)python3 bl_update/make_amj.py --type bl_update --githash $(shell git rev-parse HEAD) $(BLU_HEX_FILE) $(BLU_AMJ_FILE)

Expand Down
2 changes: 2 additions & 0 deletions bl_update/ldscript_bl_CAN.ld
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ SECTIONS
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
KEEP(*(.app_signature))
. = ALIGN(4);
} >FLASH

/* The program code and other data goes into FLASH */
Expand Down
32 changes: 31 additions & 1 deletion bl_update/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,40 @@
// dummy pin and port so we can re-use blutil.h
static GPIO_PORT_TYPE input_port;
static uint32_t input_pin;
#define FIRMWARE_RELATIVE_START 0x1000

#define MCU_FLASH_START 0x08000000


#if !DRONECAN_SUPPORT
#define FIRMWARE_RELATIVE_START 0x1000
#else

#define FIRMWARE_RELATIVE_START 0x4000

#define APP_SIGNATURE_MAGIC1 0x68f058e6
#define APP_SIGNATURE_MAGIC2 0xafcee5a0

/*
application signature, filled in by set_app_signature.py
*/
const struct {
uint32_t magic1;
uint32_t magic2;
uint32_t fwlen; // total fw length in bytes
uint32_t crc1; // crc32 up to start of app_signature
uint32_t crc2; // crc32 from end of app_signature to end of fw
char mcu[16];
uint32_t unused[2];
} app_signature __attribute__((section(".app_signature"))) = {
.magic1 = APP_SIGNATURE_MAGIC1,
.magic2 = APP_SIGNATURE_MAGIC2,
.fwlen = 0,
.crc1 = 0,
.crc2 = 0,
.mcu = AM32_MCU,
};
#endif

/*
use stringize to construct an include of the right bootloader header
*/
Expand Down
85 changes: 85 additions & 0 deletions bl_update/set_app_signature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
'''
set application signature in bin and elf files
'''

import struct
import sys

APP_SIGNATURE_MAGIC1 = 0x68f058e6
APP_SIGNATURE_MAGIC2 = 0xafcee5a0

def crc32(buf):
'''crc32 implementation'''
crc = 0
size = len(buf)
for i in range(size):
byte = buf[i]
crc ^= byte
for _ in range(8):
mask = -(crc & 1)
crc >>= 1
crc ^= (0xEDB88320 & mask)
return crc

# Example usage:
# buf = bytearray([0x31, 0x32, 0x33, 0x34]) # Sample input
# result = crc32(buf, len(buf))
# print(f"CRC32: {hex(result)}")

def set_app_descriptor(bin_file, elf_file):
'''setup app descriptor in bin file and elf file'''
descriptor = struct.pack("<II", APP_SIGNATURE_MAGIC1, APP_SIGNATURE_MAGIC2);
img = open(bin_file, 'rb').read()
len1 = len(img)
offset = img.find(descriptor)
if offset == -1:
print("No APP_DESCRIPTOR found in %s" % bin_file)
sys.exit(1)

# full descriptor length
desc_len = 44

img1 = bytearray(img[:offset])
img2 = bytearray(img[offset+desc_len:])
crc1 = crc32(img1)
crc2 = crc32(img2)

desc = struct.pack('<III', len(img), crc1, crc2)
img = img[:offset+len(descriptor)] + desc + img[offset+len(descriptor)+len(desc):]
if len(img) != len1:
print("Bad app descriptor size", len1, len(img))
sys.exit(1)
open(bin_file, 'wb').write(img)

elf_img = open(elf_file,'rb').read()
elf_ofs = elf_img.find(descriptor)
if elf_ofs == -1:
print("No APP_DESCRIPTOR found in elf file")
sys.exit(1)
elf_ofs += len(descriptor)
elf_img = elf_img[:elf_ofs] + desc + elf_img[elf_ofs+len(desc):]
open(elf_file, 'wb').write(elf_img)
print("Applied APP_DESCRIPTOR %08x%08x for %s" % (crc1, crc2, bin_file))

from argparse import ArgumentParser
parser = ArgumentParser(description="AM32 set application signature")

parser.add_argument("binfile", type=str, help="application bin file")
parser.add_argument("elffile", type=str, help="application elf file")

args = parser.parse_args()

# only apply to CAN firmwares for now
if args.binfile.find("_CAN_") == -1:
sys.exit(0)

if not args.binfile.endswith(".bin"):
print("Invalid bin file %s" % args.binfile)
sys.exit(1)

if not args.elffile.endswith(".elf"):
print("Invalid elf file %s" % args.elffile)
sys.exit(1)

set_app_descriptor(args.binfile, args.elffile)

0 comments on commit 84b3a07

Please sign in to comment.