From 9fdc27626097ae03b767a09427efc90475d90955 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 27 Nov 2017 23:08:21 -0500 Subject: Updates bootloader settings, adds file size check (#2029) * pull fuse settings for bootloader jump * fix 32a chips * make automatic bootloader selection optional * quantify bootloaders * fixs #164, speeds up dfu reset * fix for chips w/o usb * missing an n * fix bootloader sizes, use words for addresses * fix bmini, pearl, and [[ issue, make things quiet * ignore avr errors on arm for now * update settings for the light * document bootloader stuff * add bootloader title --- tmk_core/avr.mk | 10 +- tmk_core/common/avr/bootloader.c | 196 ++++++++++++++++++---------------- tmk_core/common/avr/bootloader_size.c | 20 ++++ tmk_core/rules.mk | 23 ++-- 4 files changed, 145 insertions(+), 104 deletions(-) create mode 100644 tmk_core/common/avr/bootloader_size.c (limited to 'tmk_core') diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk index 94e9a7bdbb..c083f6b72d 100644 --- a/tmk_core/avr.mk +++ b/tmk_core/avr.mk @@ -121,22 +121,22 @@ qmk: $(BUILD_DIR)/$(TARGET).hex printf "@ $(TARGET).json\n@=info.json\n" | zipnote -w $(TARGET).qmk # Program the device. -program: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep +program: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep check-size $(PROGRAM_CMD) -teensy: $(BUILD_DIR)/$(TARGET).hex +teensy: $(BUILD_DIR)/$(TARGET).hex check-size $(TEENSY_LOADER_CLI) -mmcu=$(MCU) -w -v $(BUILD_DIR)/$(TARGET).hex BATCHISP ?= batchisp -flip: $(BUILD_DIR)/$(TARGET).hex +flip: $(BUILD_DIR)/$(TARGET).hex check-size $(BATCHISP) -hardware usb -device $(MCU) -operation erase f $(BATCHISP) -hardware usb -device $(MCU) -operation loadbuffer $(BUILD_DIR)/$(TARGET).hex program $(BATCHISP) -hardware usb -device $(MCU) -operation start reset 0 DFU_PROGRAMMER ?= dfu-programmer -dfu: $(BUILD_DIR)/$(TARGET).hex sizeafter +dfu: $(BUILD_DIR)/$(TARGET).hex check-size until $(DFU_PROGRAMMER) $(MCU) get bootloader-version; do\ echo "Error: Bootloader not found. Trying again in 5s." ;\ sleep 5 ;\ @@ -168,7 +168,7 @@ dfu-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep fi $(DFU_PROGRAMMER) $(MCU) reset -avrdude: $(BUILD_DIR)/$(TARGET).hex +avrdude: $(BUILD_DIR)/$(TARGET).hex check-size if grep -q -s Microsoft /proc/version; then \ echo 'ERROR: AVR flashing cannot be automated within the Windows Subsystem for Linux (WSL) currently. Instead, take the .hex file generated and flash it using AVRDUDE, AVRDUDESS, or XLoader.'; \ else \ diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 34db8d0b0a..ee150817c3 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -6,6 +6,7 @@ #include #include #include "bootloader.h" +#include #ifdef PROTOCOL_LUFA #include @@ -56,14 +57,17 @@ * | Bootloader | 512B | Bootloader | 1KB * 0x7FFF +---------------+ 0x1FFFF +---------------+ */ -#ifndef BOOTLOADER_SIZE -#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h. -#define BOOTLOADER_SIZE 4096 -#endif -#define FLASH_SIZE (FLASHEND + 1L) -#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE) +#define FLASH_SIZE (FLASHEND + 1L) + +#if !defined(BOOTLOADER_SIZE) + uint16_t bootloader_start; +#endif +#define BOOT_SIZE_256 0b110 +#define BOOT_SIZE_512 0b100 +#define BOOT_SIZE_1024 0b010 +#define BOOT_SIZE_2048 0b000 /* * Entering the Bootloader via Software @@ -74,34 +78,62 @@ uint32_t reset_key __attribute__ ((section (".noinit"))); /* initialize MCU status by watchdog reset */ void bootloader_jump(void) { - #ifndef CATERINA_BOOTLOADER - - #ifdef PROTOCOL_LUFA - USB_Disable(); - cli(); - _delay_ms(2000); - #endif - - #ifdef PROTOCOL_PJRC - cli(); - UDCON = 1; - USBCON = (1<> 1; + } else if (high_fuse & BOOT_SIZE_512) { + bootloader_start = (FLASH_SIZE - 1024) >> 1; + } else if (high_fuse & BOOT_SIZE_1024) { + bootloader_start = (FLASH_SIZE - 2048) >> 1; + } else { + bootloader_start = (FLASH_SIZE - 4096) >> 1; + } + #endif - #else + // Something like this might work, but it compiled larger than the block above + // bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1)); + + + #if defined(BOOTLOADER_HALFKAY) + // http://www.pjrc.com/teensy/jump_to_bootloader.html + cli(); + // disable watchdog, if enabled (it's not) + // disable all peripherals + // a shutdown call might make sense here + UDCON = 1; + USBCON = (1<> 1))(); + #else + asm("ijmp" :: "z" (bootloader_start)); + #endif + } + #endif } #if 0 -/* Jumping To The Bootloader - * http://www.pjrc.com/teensy/jump_to_bootloader.html - * - * This method doen't work when using LUFA. idk why. - * - needs to initialize more regisers or interrupt setting? - */ -void bootloader_jump(void) { -#ifdef PROTOCOL_LUFA - USB_Disable(); - cli(); - _delay_ms(2000); -#endif - -#ifdef PROTOCOL_PJRC - cli(); - UDCON = 1; - USBCON = (1<. + +#include +#include + +// this is not valid C - it's for computing the size available on the chip +AVR_SIZE: FLASHEND + 1 - BOOTLOADER_SIZE \ No newline at end of file diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index 53e79ef47a..920a7f6add 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -216,6 +216,9 @@ MOVE_DEP = mv -f $(patsubst %.o,%.td,$@) $(patsubst %.o,%.d,$@) elf: $(BUILD_DIR)/$(TARGET).elf hex: $(BUILD_DIR)/$(TARGET).hex +cphex: hex + $(SILENT) || printf "Copying $(TARGET).hex to qmk_firmware folder" | $(AWK_CMD) + $(COPY) $(BUILD_DIR)/$(TARGET).hex $(TARGET).hex && $(PRINT_OK) eep: $(BUILD_DIR)/$(TARGET).eep lss: $(BUILD_DIR)/$(TARGET).lss sym: $(BUILD_DIR)/$(TARGET).sym @@ -223,19 +226,17 @@ LIBNAME=lib$(TARGET).a lib: $(LIBNAME) # Display size of file. -HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex #ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf ELFSIZE = $(SIZE) $(BUILD_DIR)/$(TARGET).elf sizebefore: - @if test -f $(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(HEXSIZE); \ + @if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(HEXSIZE); \ 2>/dev/null; $(SECHO); fi sizeafter: $(BUILD_DIR)/$(TARGET).hex - @if test -f $(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(HEXSIZE); \ + @if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(HEXSIZE); \ 2>/dev/null; $(SECHO); fi - # test file sizes eventually - # @if [[ $($(SIZE) --target=$(FORMAT) $(TARGET).hex | $(AWK) 'NR==2 {print "0x"$5}') -gt 0x200 ]]; then $(SECHO) "File is too big!"; fi # Display compiler version information. gccversion : @@ -249,8 +250,6 @@ gccversion : @if $(AUTOGEN); then \ $(SILENT) || printf "Copying $(TARGET).hex to keymaps/$(KEYMAP)/$(TARGET).hex\n"; \ $(COPY) $@ $(KEYMAP_PATH)/$(TARGET).hex; \ - else \ - $(COPY) $@ $(TARGET).hex; \ fi %.eep: %.elf @@ -371,6 +370,14 @@ show_path: @echo SRC=$(SRC) @echo OBJ=$(OBJ) +check-size: + $(eval MAX_SIZE=$(shell n=`avr-gcc -E -mmcu=$(MCU) $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | grep -oP "(?<=AVR_SIZE: ).+"`; echo $$(($$n)) || echo 0)) + $(eval CURRENT_SIZE=$(shell if [ -f $(BUILD_DIR)/$(TARGET).hex ]; then $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(AWK) 'NR==2 {print $$4}'; else printf 0; fi)) + if [ $(MAX_SIZE) -gt 0 ] && [ $(CURRENT_SIZE) -gt 0 ]; then \ + $(SILENT) || printf "$(MSG_CHECK_FILESIZE)" | $(AWK_CMD); \ + if [ $(CURRENT_SIZE) -gt $(MAX_SIZE) ]; then $(PRINT_WARNING_PLAIN); $(SILENT) || printf " * $(MSG_FILE_TOO_BIG)" ; else $(PRINT_OK); $(SILENT) || printf " * $(MSG_FILE_JUST_RIGHT)"; fi \ + fi + # Create build directory $(shell mkdir -p $(BUILD_DIR) 2>/dev/null) @@ -385,4 +392,4 @@ $(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir -p $(OUTPUT) 2>/dev/null))) .PHONY : all finish sizebefore sizeafter qmkversion \ gccversion build elf hex eep lss sym coff extcoff \ clean clean_list debug gdb-config show_path \ -program teensy dfu flip dfu-ee flip-ee dfu-start +program teensy dfu flip dfu-ee flip-ee dfu-start \ No newline at end of file -- cgit v1.2.3