比方说,我在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;
}
}
答案 0 :(得分:4)
我遇到一种情况,如果要切换回a(),b()会调用一个函数,该函数执行一些我不需要的工作。我想防止在我调用a()时发生这种情况,并最大程度地减少启动a()所需的时间
基本上,如果发生INTERRUPT_FOR_B
并且在很短的时间内发生INTERRUPT_FOR_A
,并且b()
的运行时间较长,则会发生这种情况。
您需要仔细考虑这种情况,并找出发生这种情况的机会,然后再进行过早的优化。
但是,如果要继续,可以在函数b()
中设置一些检查点,以查看run_A
是否为真。
例如
void b(void)
{
// some code.
if (run_A == true) return;
// some code
if (run_A == true) return;
// etc
}
请注意,您需要使用所有返回路径正确分析和测试b
函数,以确保该函数在所有情况下均能正常运行。
答案 1 :(得分:2)
总的来说,用一般术语来谈论这不是很有意义。这取决于您的要求以及生成中断的硬件类型。
您不能/不应该只是停止执行中的功能。最好的方法是保持函数较小并让当前函数结束,或者使函数反复轮询标志变量。
一种更具干扰性但简单的方法是简单地关闭不需要的中断,但这可能导致数据丢失。根据中断的性质,这可能会也可能不会。
当然,还有一些邪恶的方法可以使用汇编器或longjmp手动设置PC,但这是非常糟糕的做法,几乎可以肯定是对任何问题的错误解决方案。
答案 2 :(得分:0)
在旧UNIX(tm)中设计的setjmp(3)
/ longjmp(3)
函数就是这种问题。您需要在进入要中断的函数之前调用setjmp(3)
,以防万一中断来了(您必须确保要在要中断的函数的上下文中处理该中断),然后调用{ {1}},并在调用时恢复堆栈。
答案 3 :(得分:0)
听起来像您在寻找与协程类似的功能。虽然在C语言中没有直接支持,但您也许可以实现足以满足您需求的版本。如上所述,如果您想在便携式C语言中进行操作,则可能涉及setjmp / longjmp或弯腰的“ Duff's Device”。