Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

What is the easiest way to find if certain part of code is executed from ISR?

I am using FreeRTOS and some of the commands there have two flavors: for using in regular code flow and when are executed from an ISR, but in nRF SDK components and examples is  difficult to see right away all the call stack through if there is some ISR there  and errors for executing FreeRTOS regular commands from an ISR context are not always generated, so I’m curious  what will be the best practice to check if certain code is executed from any ISR down the call stack?

Thanks

Parents
  • Hi Samsam,

    The ARM register SCB->ICSR would be best thing to look into to know the context of the CPU state (ISR or Thread). I find this external page very useful when it comes to Cortex-M4 interrupt context. If you look at the ICSR section you can see that this register has VECTACTIVE register which you can poll to know the current context.

    For example if you see that

    SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk )

    Then it means that you are executing in the thread context and not in any ISR.

    A non zero number would give you the raw interrupt number from which you need to substract 16 (Since nRF implements only 4 bits of these) to get the interrupt number mapped on nRF device 

    The direct way is to use the CMSIS API as below

    IRQn_Type current_irqn = ((uint32_t)__get_IPSR()) - 16;

Reply
  • Hi Samsam,

    The ARM register SCB->ICSR would be best thing to look into to know the context of the CPU state (ISR or Thread). I find this external page very useful when it comes to Cortex-M4 interrupt context. If you look at the ICSR section you can see that this register has VECTACTIVE register which you can poll to know the current context.

    For example if you see that

    SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk )

    Then it means that you are executing in the thread context and not in any ISR.

    A non zero number would give you the raw interrupt number from which you need to substract 16 (Since nRF implements only 4 bits of these) to get the interrupt number mapped on nRF device 

    The direct way is to use the CMSIS API as below

    IRQn_Type current_irqn = ((uint32_t)__get_IPSR()) - 16;

Children
  • Hello Susheel,,

    Is there a way to see this register in debug mode at a breakpoint? I dont see this register exposed in SES in any of the registers groups :(

    Do you know what is the worst possible  consequence if use  some FreeRTOS   *FromISR() functions in non ISR context? I didnt find any visible problems so far.

    Thanks

  • samsam said:
    Is there a way to see this register in debug mode at a breakpoint? I dont see this register exposed in SES in any of the registers groups

    I put a breakpoint in FreeRTOS RTC interrupt handler, Start debugger in Segger IDE->View->Memory and put 0xE000ED04 as shown below 

    You can see that 0XE000ED04 has the value of 0x00000821

    From the register definition below

    The first six bits of the register address will give the active vector number, so, from 0X0000821, the first 6 bits will be 0x21 which is decimal 33.

    You need to substract 16 from this as this is the offset to get the platform based ISR number. So 33-16 = 17.

    From the memory map of nRF52832 you can see that number 17 is RTC1

    That is exactly we put the breakpoint and hence you can see that the SCB-ICSR value can give us the context of the interrupt you are running. If VECTACTIVE is 0, then you are running in Thread mode.

     

    samsam said:
    Do you know what is the worst possible  consequence if use  some FreeRTOS   *FromISR() functions in non ISR context? I didnt find any visible problems so far

     No one can answer you that, because the behavior is unpredictable and your system might not fail or fail eventually over time. It is not allowed to call a FromISR function from non ISR context. Instead just do below

    if (( SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk ) == 0 ))
    {
        // not inside ISR (Thread mode)
        
    }else {
      // inside  ISR
      
    }

Related