从中断处理程序中停止当前正在运行的函数

3
假设我有两个 C 函数,a() 和 b()。同时假设我有两个与两个函数对应的中断。第一个中断应该开始运行函数 a(),并在其运行时停止 b() 运行(如果在其运行过程中被中断)。类似地,第二个中断对函数 b() 也是同样的情况。
如果我当前正在运行 a(),并触发了 b() 的中断。那么如何启动 b() 并在中断处理程序完成后防止 a() 完成?
代码如下:
int main(void)
{
    Init();
    while (true)
    {
    if (run_A)
    {
      a();
      run_A = false;
    }
    if (run_B)
    {
      b();
      run_B = false;
    }   
}

void Handler(void)
{
    IntClear(interruptMask);

    if (INTERRUPT_FOR_A)
    {
        run_A = true;
    }

    if (INTERRUPT_FOR_B)
    {
        run_B = true;
    }
}

在C语言中,你唯一能做的就是定期检查a是否为真,如果是,则返回。这取决于a的实际作用,可能会很实用,也可能不实用。你需要更详细地解释一下上下文,这可能是一个XY问题 - Jabberwocky
我认为这是不可能的,但也许取决于微控制器。中断具有优先级,较高优先级不能被较低优先级停止。 - Igor Galczak
2
中断设计上会返回到调用中断的位置。你能解释一下为什么要这样做吗? - Rishikesh Raje
@RishikeshRaje 我有一个情况,其中b()调用了一个函数,该函数执行一些工作,如果我想切换回a(),则不需要这些工作。我希望在调用a()时防止它发生,并最小化启动a()所需的时间。 - atefsawaed
4个回答

4
我有一个情况,其中b()调用了一个函数,该函数会执行一些我在切换回a()时不需要的操作。我想在调用a()时防止这种情况发生,并尽量减少启动a()所需的时间。
基本上,如果INTERRUPT_FOR_B发生并且非常短的时间后发生INTERRUPT_FOR_A,那么这种情况就会发生,如果b()运行时间更长,也会发生。
在进行过早优化之前,您需要仔细思考这种情况,并找出发生的机会。
但是,如果您想继续进行,请在函数b()中设置一些检查点,以查看run_A是否为true。
例如:
void b(void)
{
    // some code.
    if (run_A == true) return;
    // some code 
    if (run_A == true) return;
    // etc
}

请注意,您需要正确地分析和测试带有所有返回路径的 b 函数,以确保该函数在所有情况下都能正确运行。

2
总体而言,一般情况下谈论这个并没有多大意义。这取决于您的需求以及生成中断的硬件类型。您不能/不应该在执行过程中随意停止函数。最好的方法是将函数保持小巧,并让当前函数完成,或者让函数反复轮询标志变量。一种更具侵入性但简单的方法是简单地关闭不需要的中断,但这可能会导致数据丢失。根据中断的性质,这可能是可以接受的,也可能不可行。当然,还有一些通过汇编或longjmp手动设置PC的邪恶方法,但这是非常糟糕的做法,几乎肯定是任何问题的错误解决方案。"最初的回答"

0
这是一种旧版UNIX(tm)中设计的setjmp(3)/longjmp(3)函数可以解决的问题。在进入要中断的函数之前,您需要调用setjmp(3),并在中断到来时(您必须确保中断在要中断的函数的上下文中处理),然后调用longjmp(3)并在调用点恢复堆栈。

0

听起来你正在寻找类似于协程的功能。虽然 C 不直接支持,但你可能能够实现一个足以满足你需求的版本。如上所述,这可能涉及 setjmp/longjmp 或令人费解的“Duff's Device”,如果你想在可移植的 C 中实现它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接