首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果函数是从ISR调用的,是否安全检测?

如果函数是从ISR调用的,是否安全检测?
EN

Stack Overflow用户
提问于 2013-05-21 03:01:40
回答 4查看 8.2K关注 0票数 18

我正在为ARM Cortex M3 (恩智浦LPC1769)微控制器开发软件。目前,我正在寻找一种机制来检测我的函数是否在ISR中被调用。我想我得查查收银机。基于这些信息,我想调用困难的函数。

我已经检查了参考手册,如果有包含必要信息的注册表。

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

有没有人知道解决我的问题的合适的寄存器/机制?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-05-21 21:42:24

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

我使用以下代码:

代码语言:javascript
复制
//! Test if in interrupt mode
inline bool isInterrupt()
{
    return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0 ;
}

SCM和SCB_ICSR_VECTACTIVE_Msk是在CMSIS (core_cm3.h)中定义的,我想它会间接地包含在您的部件特定的头文件(我猜是lpc17xx.h或类似的头文件)中。我使用的是C++,包括C中的stdbool.h将得到一个bool类型,或者更改为您自己的整数或类型定义。

然后使用它,例如:

代码语言:javascript
复制
void somefunction( char ch )
{
    if( isInterrupt() )
    {
        // Do not block if ISR
        send( ch, NO_WAIT ) ;
    }
    else
    {
        send( ch, TIMEOUT ) ;
    }
}

如果需要一个不了解体系结构的解决方案,请考虑以下几点:

代码语言:javascript
复制
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 ) ;
    }
}

然而,这个问题指的是安全地检测中断上下文,这依赖于将enter/exit宏添加到所有ISR。

票数 28
EN

Stack Overflow用户

发布于 2013-05-21 04:30:19

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

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

票数 15
EN

Stack Overflow用户

发布于 2013-05-21 04:07:32

最简单的方法是将上下文作为参数传递给函数。它也是独立于平台的。

代码语言:javascript
复制
typedef enum _context {
    normal_context = 0,
    isr_context = 1
} context;

从ISR调用函数:

代码语言:javascript
复制
func(param1, param2, isr_context);

从普通代码调用函数:

代码语言:javascript
复制
func(param1, param2, normal_context);

如果ISR代码不在您的控制之下,而您只是传递一个函数指针,那么只需使用两个不同的包装函数即可。一个将isr_context作为参数传递给函数,另一个将normal_context作为参数传递给函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16656489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档