中断时退出函数
我有一个名为 interrupt_Foo() {...}
的中断函数,它会在 1 秒过去后打开一个标志,还有一个用户定义的函数 foo_calling() {...}
调用另一个函数 foo_used() {...}
。我想在 1 秒过去后停止 foo_used() 中的进程。
下面的代码片段可能会进一步阐述我的需求:
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_used() 内的 1 秒标志是不可取的。请帮忙。
I have an interrupt function called, interrupt_Foo() {...}
which turns on a flag when 1 second has elapsed, and a user-defined function foo_calling() {...}
which calls another function foo_called() {...}
. I want to stop the process in foo_called()
when 1 second has elapsed.
The code snippet below may elaborate further my need:
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
...
}
This is real time operating system so polling the 1 second flag inside foo_called() at some portion in the code is undesirable. Please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您愿意编写不可移植的代码,并在部署之前对其进行测试,并且如果处理器支持它,则可能有一个解决方案。
当调用中断处理程序时,返回地址必须存储在某处。如果这是您的代码可以查询的位置(例如堆栈中的固定偏移量),那么您可以将该地址与函数占用的范围进行比较,以确定 'foo_scribed 是否正在执行。您可以通过存储虚拟地址、编译、解析映射文件、然后更新地址并重新编译来获取函数的地址。
然后,如果您的处理器支持,您可以将返回地址替换为 foo_called 的最后一条指令的地址。 (确保包含堆栈清理和寄存器恢复代码。)。然后正常退出中断,中断处理逻辑会将代码返回到被中断函数的末尾。
如果返回地址未存储在堆栈中,而是存储在不可写的寄存器中,则您仍然可以强制退出函数 - 如果可执行代码位于可写内存中。只需将指令存储在中断的返回地址中,然后用跳转到函数末尾的跳转指令覆盖它即可。在调用者代码中,添加一个检测器来恢复被覆盖的指令。
If you are willing to write non-portable code, and test the heck out of it before deploying it, and if the processor supports it, there may be a solution.
When the interrupt handler is called, the return address must be stored somewhere. If that is a location your code can query - like a fixed offset down the stack - then you can compare that address to the range occupied by your function to determine if 'foo_called is executing. You can get the address of the function by storing a dummy address, compiling, parsing the map file, then updating the address and recompiling.
Then, if your processor supports it, you can replace the return address with the address of the last instruction(s) of foo_called. (make sure you include the stack cleanup and register restoration code.). Then exit the interrupt as normal, and the interrupt handling logic will return code to the end of your interrupted function.
If the return address is not stored in the stack, but in an unwritable register, you still may be able to force quit your function - if the executable code is in writrable memory. Just store the instruction at the interruupt's return address, then overwrite it with a jump instruction which jumps to the function end. In the caller code, add a detector which restored the overwritten instruction.
我希望您的 RTOS 具有某种计时器信号/中断,您可以使用它在一秒过去时通知您。例如,如果它是实时 UNIX/Linux,那么您将为 SIGALRM 设置信号处理程序一秒钟。在 Linux 的 RT 变体上,与非 RT 变体相比,该信号将具有更大的粒度和更好的保证。但将信号设置为略小于一秒并忙等待(循环)直到达到一秒仍然是一个好主意。
I would expect that your RTOS has some kind of timer signal/interrupt that you can use to notify you when one second has passed. For instance if it is a realtime UNIX/Linux then you would set a signal handler for SIGALRM for one second. On a RT variant of Linux this signal will have more granularity and better guarantees than on a non-RT variant. But it is still a good idea to set the signal for slightly less than a second and busy-wait (loop) until you reach one second.