From 90f6c9714f2672ffcf9aa24e537067928b17cc99 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Thu, 12 Nov 2015 16:40:47 +0000 Subject: [PATCH 1/2] Fix assembly sequence to start bootloader in GCC The assemble sequence within an mbedOS application that starts the nordic bootloader was being modified by the compiler. The result is that DFU enabled applications could never start the bootloader correctly. This is because the GCC compiler was translating a MOV instruction into a ADDS, which sets the conditional flags in APSR before a conditional branch was executed. The result of the incorrect branch caused the program to believe that it was in interrupt mode when this was not the case. --- .../components/libraries/bootloader_dfu/bootloader_util_arm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c b/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c index a24b745..753d434 100644 --- a/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c +++ b/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c @@ -100,8 +100,8 @@ static void bootloader_util_reset(uint32_t start_addr) "LDR r2, =MASK_ZEROS\n\t" /* Load zeros to R2 */ "MRS r3, IPSR \n\t" /* Load IPSR to R3 to check for handler or thread mode */ - "CMP r2, r3 \n\t" /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */ "MOV R0, R6 \n\t" + "CMP r2, r3 \n\t" /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */ "BNE isr_abort \n\t" /* If not zero we need to exit current ISR and jump to reset handler of bootloader */ "LDR r4, =MASK_ONES \n\t" /* Load ones to R4 to be placed in Link Register. */ From c8cb3aeee383114ace230538209fc62837e2c6f4 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 13 Nov 2015 09:42:12 +0000 Subject: [PATCH 2/2] Change assembly sequence to avoid changing APSR Change assembly sequence that starts the Nordic bootloader to remove MOV instruction before cheks of IPSR. The MOV might be translated into a ADDS that could change the APSR and cause a wrong branch to be taken. --- .../components/libraries/bootloader_dfu/bootloader_util_arm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c b/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c index 753d434..bbd4496 100644 --- a/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c +++ b/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c @@ -59,10 +59,10 @@ EXC_RETURN_CMD EQU 0xFFFFFFF9 ; EXC_RETURN for ARM Cortex. When loaded to PC t MSR MSP, R5 ; Set the main stack pointer to the applications MSP. LDR R6, [R0, #0x04] ; Load Reset handler into register 6. + MOV R0, R6 LDR R2, =MASK_ZEROS ; Load zeros to R2 MRS R3, IPSR ; Load IPSR to R3 to check for handler or thread mode CMP R2, R3 ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader - MOV R0, R6 BNE isr_abort ; If not zero we need to exit current ISR and jump to reset handler of bootloader LDR R4, =MASK_ONES ; Load ones to R4 to be placed in Link Register. @@ -98,9 +98,9 @@ static void bootloader_util_reset(uint32_t start_addr) "MSR MSP, r5 \n\t" /* Set the main stack pointer to the applications MSP. */ "LDR r6,[r0, #0x04] \n\t" /* Load Reset handler into register 0. */ + "MOV R0, R6 \n\t" "LDR r2, =MASK_ZEROS\n\t" /* Load zeros to R2 */ "MRS r3, IPSR \n\t" /* Load IPSR to R3 to check for handler or thread mode */ - "MOV R0, R6 \n\t" "CMP r2, r3 \n\t" /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */ "BNE isr_abort \n\t" /* If not zero we need to exit current ISR and jump to reset handler of bootloader */