C如何定义可由预处理器检查的上下文

时间:2017-08-29 13:39:46

标签: c gcc macros preprocessor

在嵌入式系统上,我有一个函数,不能从中断上下文中调用。我想确保在编译时检查它。我想,如果预处理器可以检查这个会很好。我想到这样的事情:

/* function that shall not be called from interrupt-context */
void function_not_to_call_from_isr(void)
{
    #ifdef INTERRUPT_CONTEXT
        #error This shall not be called from interrupt context!
    #endif
    // ... stuff ...
}

void someISRfunction(void)
{
#define INTERRUPT_CONTEXT
    // here, the check can be performed
    function_not_to_call_from_isr();
#undef INTERRUPT_CONTEXT
}

我的问题是,可以做一些魔术,这样我就不必手动定义/取消定义INTERRUPT_CONTEXT吗? 像:

#define INTERRUPT_SERVICE_ROUTINE(funcName) void funcName(void) // magic needed here...

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

如果你想阻止从上下文调用函数,那么在预处理器中使用你想要的方式是不可能的,特别是在编译时不能。

对于特定的体系结构,您可以检查是否处于中断上下文中,然后确定要执行的操作。下面的示例适用于带有CMSIS代码的ARM Cortex-M。

void func_prohibited_in_isr(void) {
    if (__get_IPSR()) {
        //Called from IRQ, return
        return;
    }
    //Other code, executed when function is not called from IRQ
}

//IRQ function for peripheral
void IRQ_Handler(void) {
    func_prohibited_in_isr(); //Will do nothing when called
}

因此,如果您处于IRQ环境中,则必须了解如何检查特定体系结构。

答案 1 :(得分:1)

您无法在实际编译之前扩展所有#define。你需要一个变量

#define INTERRUPT_CONTEXT_ENTRY do {frominterrupt++;} while(0)
#define INTERRUPT_CONTEXT_EXIT  do {frominterrupt--;} while(0)
#define FROM_INTERRUPT  (frominterrupt > 0)
#define ISR_PANIC (frominterrupt < 0)

volatile int frominterrupt = 0;


void interrupt_handler()
{
    INTERRUPT_CONTEXT_ENTRY;
    /* do something*/
    INTERRUPT_CONTEXT_EXIT;
}

void function_not_to_call_from_isr(void)
{
    if(ISR_PANIC)
    {
         /* start the suicide procedure */
         /* your program is dead anyway */
    }

    if(FROM_INTERRUPT)
    {
        /* do something - illegal call */
    }
    else
    {
        /* do normall stuff */
    }
}