如何在不重构的情况下跳出并恢复c代码中的任意位置

如何在不重构的情况下跳出并恢复c代码中的任意位置,c,embedded,micropython,C,Embedded,Micropython,背景 我正在集成到我的定制协作式多任务操作系统中(不,我的公司不会改为先发制人) Micropython使用,这比我分配的时间片花费的时间多得多,即使没有什么可收集的,例如,我连续两次调用它,对它进行计时,但仍然需要很多时间 显而易见的解决方案 是的,我可以重构micropython源代码,但只要有变化 理想溶液 理想的解决方案是调用一些函数void pause(&func\u in\u call\u stack),这些函数将跳出,保持堆栈完整,一直到调用堆栈顶部的函数,比如main。而恢复将。

背景

我正在集成到我的定制协作式多任务操作系统中(不,我的公司不会改为先发制人)

Micropython使用,这比我分配的时间片花费的时间多得多,即使没有什么可收集的,例如,我连续两次调用它,对它进行计时,但仍然需要很多时间

显而易见的解决方案

是的,我可以重构micropython源代码,但只要有变化

理想溶液

理想的解决方案是调用一些函数
void pause(&func\u in\u call\u stack)
,这些函数将跳出,保持堆栈完整,一直到调用堆栈顶部的函数,比如
main
。而
恢复
将。恢复

问题

是否可以使用C和汇编来实现
暂停

更新


写这篇文章时,我意识到基于C的异常处理代码已经完成了我所需要的大部分工作。

您的问题是关于实现上下文切换的。正如我们在评论中详尽介绍的那样,支持上下文切换是任何多任务系统,尤其是多任务操作系统的关键特征之一。因为您假定操作系统不支持上下文切换,所以您正在谈论为单任务操作系统实现多任务

<>你把OS描述为提供某种任务队列(“放弃控制,一个线程必须退出它的运行循环”)不会改变这一点,虽然在某种程度上我们可以认为它是语义问题。我想象这样一个系统的典型任务将通过创建和执行一系列微任务(运行循环的工作)来运行,为每个微任务提供一个共享的、可变的内存上下文。这样的运行循环可以安全地退出,然后再重新进入,以从停止的位置继续生成微任务

在肯定性应用程序行动(即您的
pause()
)定义的边界处将任务划分为微任务将取决于ISO C提供的能力之外的能力。但是,很有可能在某些组件的帮助下,再加上某种框架支持来完成。你至少需要这些东西:

  • 记录任务当前执行上下文的机制——堆栈、寄存器内容,可能还有其他详细信息。这本质上是特定于系统的
  • 存储记录的执行上下文的任务关联位置。有多种方式可以建立这样一个东西。有希望的替代方案包括(i)由操作系统提供;(ii)由运行在操作系统之上的某种userland多任务系统提供;(iii)由编译器内置到任务中
  • 恢复记录的执行上下文的机制——这也是系统特定的
<>如果OS不提供这样的特性,那么您可以考虑将(现在删除的)POSIX上下文系统作为记录和恢复执行上下文的模型接口。(请参见,
swapcontext()
setcontext()
)但是,您需要自己实现这些功能,并且您可能希望包装它们以向应用程序提供更简单的接口。详细信息将高度依赖于硬件和底层操作系统


作为替代方案,您可以通过提供发出特殊指令代码(即,比您需要的更特殊指令代码)的编译器,为此类系统实现透明的多任务支持。例如,考虑为您自己设计的VM发射字节码的编译器。运行结果程序的虚拟机自然会跟踪其中运行的程序的状态,并且在每个操作码序列之后都会产生一定数量的操作码。

暂停()
和以后的
恢复之间,代码需要做什么?@chux将调用其他代码,将控制权交给RTO。然后,一旦micropy线程得到时间片,就会调用
resume
。分配给你的时间片有多长?@user3386109大约100us;gc需要600us@Adrian,让我们不要讨论假设。如果您的操作系统不提供我所描述的系统调用,那么我不认为它可以被描述为“协作多任务操作系统”。在这种情况下,一定要纠正你的问题,以便更准确地描述你的情况。另一方面,如果您的操作系统确实提供了这样的系统调用,那么它们就是用于您描述的目的的正确工具。因此,寻求替代方案是毫无意义的。