中断时退出功能

时间:2011-09-26 18:51:30

标签: c microcontroller interrupt

我有一个叫做interrupt_Foo() {...}的中断函数,它在1秒后打开一个标志,用户定义的函数foo_calling() {...}调用另一个函数foo_called() {...}。我希望在1秒后停止foo_called()中的过程。

下面的代码段可能会进一步阐述我的需求:

void interrupt interrupt_foo() {
   ...
   if(1 second has elapsed) {
      flag1s = 1;
   } else {
      flag1s = 0;
   }
}

void foo_calling() {
   // need something here to stop the process of foo_called()
   ...
   (*fptr_called)(); // ptr to function which points to foo_called
   ...
}

void foo_called() {
   // or something here to stop the process of this function
   ...
   // long code
   ...
}

这是实时操作系统,因此在代码的某个部分轮询foo_called()内的1秒标志是不可取的。请帮忙。

2 个答案:

答案 0 :(得分:2)

如果您愿意编写非可移植代码,并在部署之前测试它,并且如果处理器支持它,则可能有解决方案。

调用中断处理程序时,必须将返回地址存储在某处。如果这是您的代码可以查询的位置 - 比如堆栈中的固定偏移量 - 那么您可以将该地址与函数占用的范围进行比较,以确定'foo_called是否正在执行。您可以通过存储虚拟地址,编译,解析映射文件,然后更新地址和重新编译来获取函数的地址。

然后,如果您的处理器支持它,您可以将返回地址替换为foo_called的最后一条指令的地址。 (确保包括堆栈清理并注册恢复代码。)。然后正常退出中断,中断处理逻辑将代码返回到被中断函数的末尾。

如果返回地址没有存储在堆栈中,而是存储在一个不可写入的寄存器中,您仍然可以强制退出您的函数 - 如果可执行代码在可写内存中。只需将指令存储在interruupt的返回地址,然后用跳转指令覆盖它,跳转到函数结束。在调用者代码中,添加一个恢复覆盖指令的检测器。

答案 1 :(得分:1)

我希望你的RTOS有一些定时器信号/中断,你可以用它来通知你一秒钟过去。例如,如果它是实时UNIX / Linux,那么您将为SIGALRM设置信号处理程序一秒钟。在Linux的RT变体上,与非RT变体相比,此信号将具有更多粒度和更好的保证。但是将信号设置为略小于一秒并且忙等待(循环)直到达到一秒仍然是个好主意。