Interrupt Control State Registerの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 型が取得されるか、独自の int または typedef に変更されます。
次に、たとえば次のように使用されます。
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 ) ;
}
}
ただし、問題は割り込みコンテキストを安全に検出することであり、これはすべてのISRに追加されている開始/終了マクロに依存しています。