AnsweredAssumed Answered

Can NMI pre-empt the Reset Handler on the Kinetis K24FN1M0?

Question asked by DaveTonyCook on Apr 4, 2016
Latest reply on Apr 4, 2016 by Mark Butcher



Its my understanding that the Reset vector is at a higher priority than NMI and that the NMI should pend to be executed on return from the reset handler. [Sec 7.4 p247,248 Definitive Guide to ARM cortex..]


However when I run in debug starting at the reset vector (i.e. not from main) and I force the NMI line low in hardware before running the code. The NMI handler interrupts immediately.  This has left me confused.... is this behaviour because the code is running from the debugger or is my understanding of the interrupt priority scheme incorrect?




I have a hardware problem that asserts NMI at power-up.  Whilst waiting for the hardware fix I thought I could fix this in software by controlling the code that runs in the NMI Handler using the variable NMI_armed


The problem with this approach is that it relies on the ROM COPY function to execute without being pre-empted. The rom

copy is performed by the DLIB function   __iar_data_init3 and is called from within the reset handler.  It was my assumption, that because this code is in the reset handler that the NMI couldn't pre-empt it.


Code snippet from the IAR supplied startup_MK24F12.s



        DCD     sfe(CSTACK)

        DCD     Reset_Handler                                   ;Reset Handler             (priority -3)

        DCD     NMI_Handler                                      ;NMI Handler                (priority -2)

        DCD     HardFault_Handler                             ;Hard Fault Handler     (priority -1)

        DCD     MemManage_Handler                        ;MPU Fault Handler     (programmable)

        DCD     BusFault_Handler                               ;Bus Fault Handler      (programmable)

        DCD     UsageFault_Handler                           ;Usage Fault Handler  (programmable)



        PUBWEAK Reset_Handler



        CPSID   I               ; Mask interrupts PRIMASK

        LDR R0, =_NVIC_ICER0    ; Disable interrupts and clear pending flags

        LDR R1, =_NVIC_ICPR0

        LDR R2, =0xFFFFFFFF

        MOV R3, #8


        CBZ R3, _irq_clear_end

        STR R2, [R0], #4        ; NVIC_ICERx - clear enable IRQ register

        STR R2, [R1], #4        ; NVIC_ICPRx - clear pending IRQ register

        SUB R3, R3, #1

        B _irq_clear


        LDR     R0, =SystemInit

        BLX     R0

        LDR     R0, =init_data_bss

        BLX     R0

        CPSIE   I               ; Unmask interrupts

        LDR     R0, =__iar_program_start        ; calls __iar_data_init3 before entering main()

        BX      R0



        PUBWEAK NMI_Handler


NMI_Handler      ;Implemented in 'C' in prw_fail.c

        B .


In my module prw_fail.c




        if(NMI_armed)        // NMI_armed controlled in main() as I only want to be true on power down


                //do stuff