2011-09-26 79 views
1

我有一个叫做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 
    ... 
} 

这是实时操作系统,以便轮询1个第二标志内foo_called()在代码中的一些部分是不希望的。请帮忙。

+2

否则怎么你所期望的功能停止不投票的标志?你宁愿杀死线程吗?这听起来不像是最好的选择恕我直言。 –

+0

这是我的问题。由于这是针对微控制器(即PIC)的,所以线程可能具有复杂的实现。如果在微控制器中做先发制人的RTOS似乎是不可能的,那么我会采用轮询而不是最后的手段。 –

+1

我和杰夫在一起,我认为解决这个问题的唯一方法就是通过查询这个变量。根据foo_called()中的内容,有很多聪明的方法可以进行轮询,比如使用标记值或类似的东西。我看到你解决这个问题的唯一方法是,如果你正在编写/编辑实时操作系统,并以某种方式改变信号处理程序中的TCB,并且有一种聪明的方法来管理它。 – dbeer

回答

2

如果你愿意写不可移植的代码,并且在部署之前测试赫克出来,如果处理器支持的话,有可能是一个解决方案。

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

然后,如果你的处理器支持的话,你可以用foo_called最后一条指令(一个或多个)地址替换返回地址。 (确保包含堆栈清理和注册恢复代码。)。然后正常退出中断,中断处理逻辑将代码返回到中断函数的结尾。

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

1

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