cortex-m0上ISR的杀伤功能

cortex-m0上ISR的杀伤功能,c,stack,embedded,cortex-m,C,Stack,Embedded,Cortex M,我使用的是Cortex-M0处理器,带有裸机实现(无操作系统)。我们有一个固件应用程序,我们希望允许第三方编写一个C函数,该函数将独立于其余固件构建并加载到内存中(有点像DLL),如果检测到,则由主固件调用 我遇到的问题是,我希望在受保护的环境中运行此外部功能,以便在它创建故障异常或执行时间过长时不会中断主固件。因此,我想做的是,从硬故障ISR(针对故障异常)或计时器勾选ISR(针对执行时间问题),操纵堆栈以终止外部函数并将执行返回到主固件。我意识到这在RTOS中是直截了当的,但是主固件已经开发

我使用的是Cortex-M0处理器,带有裸机实现(无操作系统)。我们有一个固件应用程序,我们希望允许第三方编写一个C函数,该函数将独立于其余固件构建并加载到内存中(有点像DLL),如果检测到,则由主固件调用

我遇到的问题是,我希望在受保护的环境中运行此外部功能,以便在它创建故障异常或执行时间过长时不会中断主固件。因此,我想做的是,从硬故障ISR(针对故障异常)或计时器勾选ISR(针对执行时间问题),操纵堆栈以终止外部函数并将执行返回到主固件。我意识到这在RTOS中是直截了当的,但是主固件已经开发出来了,在这一点上切换它需要花费大量的精力


我使用了TestCcatch C++,但编译器似乎并不支持它。因此,我看到的另一个选项是在调用外部函数之前编写一些程序集来保存堆栈指针,然后从ISR恢复SP和上下文,并分支到主固件中的返回点。有谁能给我一些建议,告诉我如何最好地做到这一点,或者有没有更简单的方法来完成这一点?

这是我最后使用的实现。我使用CMSIS内部函数_get_MSP()和_set_MSP()访问SP。在调用受保护函数之前,我保存了当前SP。返回地址是该函数推送到堆栈上的第一项,因此,我将保存的SP增加一个位置,使其指向故障恢复情况中使用的返回地址

计时器滴答声ISR跟踪受保护功能运行的时间,如果超时或发生硬故障中断,则执行故障处理程序。首先需要退出中断上下文(否则您将从中断上下文执行主代码,以防止进一步的中断),因此我确定了相对于SP的哪个堆栈位置保存ISR返回地址,并用故障恢复函数的地址覆盖它。请注意,计时器滴答声ISR处于最低优先级,因此返回地址始终为非中断代码。如果ISR优先级更高,则可能不是这样,但我没有验证它

从任一ISR退出时,执行故障恢复功能。它需要两个说明:

__set_MSP( StackPtrSave );
__asm volatile ("pop {pc}");
这会将SP和PC恢复到其正确状态,就像受保护功能刚刚退出一样。但是,它不会恢复任何其他寄存器。如果返回点位于函数的末尾(并且编译器不尝试内联它),则应该可以。在我的例子中,我需要设置StackPtrSave=0,因为这是ISR知道受保护函数何时运行的方式。我尝试使用易失性指针强制编译器在恢复后将变量的地址重新加载到寄存器中,但无法使其工作。最后,我设置了一个属性来禁用函数的优化,这样它在写入StackPtrSave之前总是会加载地址


如评论中所述,这并不能提供一个完全受保护的环境。受保护的函数仍然可以使用指针来损坏静态变量或堆栈。由于Cortex-m0没有记忆保护装置,我看不到任何方法可以避免这种情况。在我的例子中,负责受保护功能的第三方确实对产品的功能感兴趣,因此我给出了一些指导原则,他们的代码避免使用指针或数组。我认为这提供了此平台上可以提供的最高级别的保护。

使用RTO并不容易,因为它们没有动态加载/执行的规定。您仍然需要为该函数提供自己的包装器。问题不是捕获异常并回滚堆栈,而是防止该函数链接RAM。MPU是否足够完全取决于内存布局和您希望允许的功能。例如,如果堆栈不只是自己的,它可能会损坏堆栈。您是否有可能使用一种很小的解释语言而不是本机代码来阻止对第三方代码的直接CPU/内存访问?Brian-我们确实使用类似于解释汇编的语言(使用excel作为汇编程序)进行了初步实现。然而,逻辑需求变得如此复杂,以至于在汇编程序中编写代码非常繁重。因此,我们决定切换到C。第三部分将不能直接访问任何静态内存。它们将被赋予访问固定大小的控制值数组的函数。它们在堆栈上使用局部变量是一个值得关注的问题。Cortex-m0确实有一个进程堆栈,我可以用于此,但现在我认为我们将提供一些关于局部变量使用的规则。我认为Cortex-m0没有完全的保护(如果有的话),因此这个覆盖的应用程序可以丢弃一些东西,包括保护你不受其影响的东西。我不认为RTOS可以发明一些你还没有的东西(保护)(除非你的芯片中有PMSA,请参阅arm文档),但实际上你正在做的是创建一个类似的操作系统。因此,您可以对代码进行计时器检查,看看它是否有任何时间片,等等,或者以某种方式检测程序是否丢失,但我认为一个行为不好的程序通常会使您崩溃