From dd3e685bf00efbec6ea6533b3a2ad01ccaf89cfb Mon Sep 17 00:00:00 2001 From: Michal Moskal Date: Mon, 21 Nov 2016 22:05:39 -0600 Subject: [PATCH] Add user-space program to update bootloader --- Makefile | 11 +++++++---- TODO.md | 5 ++++- inc/uf2.h | 3 ++- scripts/samd21j18a_self.ld | 2 +- src/main.c | 9 +++------ src/selfmain.c | 8 ++++++++ src/utils.c | 7 +++++++ 7 files changed, 32 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 8a60cd89..5a58e682 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ SELF_OBJECTS = $(patsubst src/%.c,$(BUILD_PATH)/%.o,$(SELF_SOURCES)) $(BUILD_PAT NAME=uf2-bootloader EXECUTABLE=$(BUILD_PATH)/$(NAME).bin -SELF_EXECUTABLE=$(BUILD_PATH)/self-$(NAME).bin +SELF_EXECUTABLE=$(BUILD_PATH)/self-$(NAME).uf2 all: dirs $(EXECUTABLE) $(SELF_EXECUTABLE) build/uf2conv @@ -73,6 +73,9 @@ wait: logs: sh scripts/getlogs.sh $(BUILD_PATH)/$(NAME).map +selflogs: + sh scripts/getlogs.sh $(BUILD_PATH)/self-$(NAME).map + dirs: @echo "Building $(BOARD)" -@mkdir -p $(BUILD_PATH) @@ -86,12 +89,12 @@ $(EXECUTABLE): $(OBJECTS) @node -p '"Free space: " + (8192 - require("fs").readFileSync("$(BUILD_PATH)/$(NAME).bin").length)' -$(SELF_EXECUTABLE): $(SELF_OBJECTS) +$(SELF_EXECUTABLE): $(SELF_OBJECTS) build/uf2conv $(CC) -L$(BUILD_PATH) $(LDFLAGS) \ -T./scripts/samd21j18a_self.ld \ -Wl,-Map,$(BUILD_PATH)/self-$(NAME).map -o $(BUILD_PATH)/self-$(NAME).elf $(SELF_OBJECTS) - arm-none-eabi-objcopy -O binary $(BUILD_PATH)/self-$(NAME).elf $@ - + arm-none-eabi-objcopy -O binary $(BUILD_PATH)/self-$(NAME).elf $(BUILD_PATH)/self-$(NAME).bin + ./build/uf2conv $(BUILD_PATH)/self-$(NAME).bin $@ $(BUILD_PATH)/%.o: src/%.c $(wildcard inc/*.h) @echo "$<" diff --git a/TODO.md b/TODO.md index 1f861706..73354563 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,10 @@ * [x] organize board configs in directories * [x] if `!USE_CDC && !USE_UART` - don't compile monitor * [x] if `!USE_CDC` don't compile the CDC code (not only exclude descriptors) -* [ ] write user program for updating bootloader +* [x] write user program for updating bootloader +* [ ] document self-updater +* [ ] write u2fconv in .js +* [ ] investigate some blinking ## Bigger * [ ] look into reset into bootloader from host to continue flashing diff --git a/inc/uf2.h b/inc/uf2.h index 133f6953..5fc20f11 100644 --- a/inc/uf2.h +++ b/inc/uf2.h @@ -21,7 +21,7 @@ #define INDEX_URL "https://www.pxt.io/" #endif -#define UF2_VERSION "v1.0.0" +#define UF2_VERSION "v1.0.5" // needs to be more than ~4200 (to force FAT16) #define NUM_FAT_BLOCKS 8000 @@ -123,6 +123,7 @@ inline void bulb_off(void) { PORT->Group[BULB_PORT].OUTCLR.reg = (1 << BULB_PIN) extern uint32_t timerHigh, resetHorizon, blinkHorizon; void timerTick(void); +void delay(uint32_t ms); #define CONCAT_1(a, b) a ## b #define CONCAT_0(a, b) CONCAT_1(a, b) diff --git a/scripts/samd21j18a_self.ld b/scripts/samd21j18a_self.ld index 782ca5c5..4c3e9ef9 100644 --- a/scripts/samd21j18a_self.ld +++ b/scripts/samd21j18a_self.ld @@ -49,7 +49,7 @@ SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { - rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000 + rom (rx) : ORIGIN = 0x00002000, LENGTH = 0x00020000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } diff --git a/src/main.c b/src/main.c index 69d68fce..d28fddee 100644 --- a/src/main.c +++ b/src/main.c @@ -92,10 +92,9 @@ static void check_start_application(void) { /** * Test reset vector of application @APP_START_ADDRESS+4 - * Stay in SAM-BA if *(APP_START+0x4) == 0xFFFFFFFF - * Application erased condition + * Sanity check on the Reset_Handler address */ - if (app_start_address == 0xFFFFFFFF) { + if (app_start_address < APP_START_ADDRESS || app_start_address > FLASH_SIZE) { /* Stay in bootloader */ return; } @@ -108,9 +107,7 @@ static void check_start_application(void) { } else { if (*DBL_TAP_PTR != DBL_TAP_MAGIC_QUICK_BOOT) { *DBL_TAP_PTR = DBL_TAP_MAGIC; - for (int i = 1; i < 100000; ++i) { - asm("nop"); - } + delay(500); } *DBL_TAP_PTR = 0; } diff --git a/src/selfmain.c b/src/selfmain.c index 6c41b7ae..f2f0faba 100644 --- a/src/selfmain.c +++ b/src/selfmain.c @@ -44,6 +44,14 @@ int main(void) { logmsg("Update successful!"); + // erase first row of this updater app, so the bootloader doesn't start us again + flash_erase_row((void*)i); + + for (i = 0; i < 20; ++i) { + bulb_toggle(); + delay(200); + } + bulb_off(); resetIntoBootloader(); diff --git a/src/utils.c b/src/utils.c index eac1654f..4e3ac2b0 100644 --- a/src/utils.c +++ b/src/utils.c @@ -3,6 +3,13 @@ static uint32_t timerLow; uint32_t timerHigh, resetHorizon, blinkHorizon; +void delay(uint32_t ms) { + ms <<= 8; + for (int i = 1; i < ms; ++i) { + asm("nop"); + } +} + void timerTick(void) { if (timerLow-- == 0) { timerLow = TIMER_STEP;