如果从ISR调用函数,则安全检测?

fer*_*ith 17 embedded cortex-m3

我正在为ARM Cortex M3(NXP LPC1769)微控制器开发软件.目前我正在寻找机制以检测我的功能是否在ISR中被调用.我认为我必须检查一个寄存器.基于这些信息,我想称之为困难的功能.

如果有一个包含必要信息的寄存器,我已经检查了参考手册.

例如,我试图根据"中断有效位寄存器"(IABR)寄存器检测我是否从ISR(我使用SysTick-ISR)调用.如果ISR处于活动状态,该寄存器应为!= 0.但值为0x00000000.这意味着没有中断处于活动状态.除了这个测试,我在参考手册中检查了NVIC和SC寄存器,搜索包含必要标志的寄存器,但我没有找到.

有没有人知道我的问题适合的注册/机制?

Cli*_*ord 27

您需要测试中断控制状态寄存器VECTACTIVE字段.

我使用以下内容:

//! Test if in interrupt mode
inline bool isInterrupt()
{
    return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0 ;
}
Run Code Online (Sandbox Code Playgroud)

SCM和SCB_ICSR_VECTACTIVE_Msk在CMSIS(core_cm3.h)中定义,我想这将由您的部分特定标题(lpc17xx.h或类似的猜测)间接包含在内.我使用C++,包括在C中的stdbool.h将获得bool类型,或更改为您自己的int或typedef.

然后使用它,例如:

void somefunction( char ch )
{
    if( isInterrupt() )
    {
        // Do not block if ISR
        send( ch, NO_WAIT ) ;
    }
    else
    {
        send( ch, TIMEOUT ) ;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果需要一个假设不了解架构的解决方案,请考虑以下事项:

volatile int interrupt_nest_count = 0 ;
#define ENTER_ISR() interrupt_nest_count++
#define EXIT_ISR()  interrupt_nest_count--
#define IN_ISR() (interrupt_nest_count != 0)

void isrA()
{
     ENTER_ISR() ;
     somefunction( 'a' ) ;
     EXIT_ISR() ;
}

void isrB()
{
     ENTER_ISR() ;
     somefunction( 'b' ) ;
     EXIT_ISR() ;
}

void somefunction( char ch )
{
    if( IN_ISR() )
    {
        // Do not block if ISR
        send( ch, NO_WAIT ) ;
    }
    else
    {
        send( ch, TIMEOUT ) ;
    }
}
Run Code Online (Sandbox Code Playgroud)

但问题是安全地检测中断上下文,这依赖于将进入/退出宏添加到所有 ISR.

  • @Groo:我想我在答案中也说了多少.很久以前 - 如果今天回答,也许我会省略第二个. (2认同)

fer*_*ith 14

经过一些讨论和更多搜索后,我找到了正确的寄存器:中断程序状态寄存器:IPSR包含当前中断服务程序(ISR)的异常类型号.有关其属性,请参见表626中的寄存​​器摘要.

如果未从isr调用函数,则寄存器的值为IPSR == 0