我正在为ARM Cortex M3 (恩智浦LPC1769)微控制器开发软件。目前,我正在寻找一种机制来检测我的函数是否在ISR中被调用。我想我得查查收银机。基于这些信息,我想调用困难的函数。
我已经检查了参考手册,如果有包含必要信息的注册表。
例如,我尝试检测是否从基于“中断活动位寄存器”(IABR)寄存器的ISR (我使用SysTick-ISR)调用我。如果ISR有效,则该寄存器应为!= 0。但是值是0x00000000。这意味着没有处于活动状态的中断。除了这个测试,我检查了参考手册中的NVIC和SC寄存器,寻找一个包含必要标志的寄存器,但我没有找到。
有没有人知道解决我的问题的合适的寄存器/机制?
发布于 2013-05-21 21:42:24
您需要测试中断控制状态寄存器的VECTACTIVE字段。
我使用以下代码:
//! 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类型,或者更改为您自己的整数或类型定义。
然后使用它,例如:
void somefunction( char ch )
{
if( isInterrupt() )
{
// Do not block if ISR
send( ch, NO_WAIT ) ;
}
else
{
send( ch, TIMEOUT ) ;
}
}如果需要一个不了解体系结构的解决方案,请考虑以下几点:
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。
发布于 2013-05-21 04:30:19
经过一些讨论和更多的搜索,我找到了正确的寄存器:中断程序状态寄存器: IPSR包含当前中断服务例程(ISR)的异常类型编号。有关其属性,请参见表626中的寄存器摘要。
如果函数不是从isr调用的,则寄存器的值为IPSR == 0
发布于 2013-05-21 04:07:32
最简单的方法是将上下文作为参数传递给函数。它也是独立于平台的。
typedef enum _context {
normal_context = 0,
isr_context = 1
} context;从ISR调用函数:
func(param1, param2, isr_context);从普通代码调用函数:
func(param1, param2, normal_context);如果ISR代码不在您的控制之下,而您只是传递一个函数指针,那么只需使用两个不同的包装函数即可。一个将isr_context作为参数传递给函数,另一个将normal_context作为参数传递给函数。
https://stackoverflow.com/questions/16656489
复制相似问题