This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Interrupt in Bootloader not working

I'm using interrupt_handler.c for a bootloader without a softdevice from this source. Interrupt handling in the main app seems to work fine. But interrupts in the bootloader leading to a reset.

For example my uart interrupt.

  1. on an uart interrupt section bootloop is called
  2. jumps to uart0
  3. jumps to execute
  4. execute jumps to 0x0000 0000

Why?

[uart.c]
void UART0_IRQHandler_Bootloader(void)
{
    // some code
}


[interrupt_handler.c]
bootload 
        CMP R0, #0x24;
        BEQ swi0
        CMP R0, #0x21;
        BEQ rtc1
        CMP R0, #0x16;
        BEQ gpiote
        CMP R0, #0x12;
        BEQ uart0
        //RETURN code needed
uart0
        EXTERN  UART0_IRQHandler_Bootloader[WEAK]     
        LDR    R0,=UART0_IRQHandler_Bootloader
        B execute ;            
execute            
        BX     R0  ;

I did some investigations: R0 is loaded with 0x0000 0000 is above example. When removing [WEAK] everything works as expected. Leaving [WEAK] linker (Keil 5.14) is removing UART0_IRQHandler_Bootloader section.

Removing Unused input sections from the image.

    Removing main.o(.rev16_text), (4 bytes).
    Removing main.o(.revsh_text), (4 bytes).
    Removing main.o(i.init), (60 bytes).
    Removing uartreader.o(.rev16_text), (4 bytes).
    Removing uartreader.o(.revsh_text), (4 bytes).
    Removing uartreader.o(i.UART0_IRQHandler_Bootloader), (140 bytes).
    Removing uartreader.o(.bss), (50 bytes).
    Removing arm_startup_nrf51.o(HEAP), (1024 bytes).
    Removing system_nrf51.o(.rev16_text), (4 bytes).
    Removing system_nrf51.o(.revsh_text), (4 bytes).
    Removing system_nrf51.o(i.SystemCoreClockUpdate), (16 bytes).

11 unused section(s) (total 1314 bytes) removed from the image.
Related