繁体   English   中英

stm32-中断句柄

[英]stm32 - Interrupt handle

在外部中断功能中,我想通过调用主功能来复位。 但是之后,如果我有一个新的中断触发器,MCU会认为它正在处理中断函数,并且不会再次调用中断函数。 我的解决方案是什么? (在我的项目中,不允许调用软重置功能)

在任何情况下调用main()都是一个糟糕的主意,从中断处理程序中调用它是一个非常糟糕的主意,正如您所发现的那样。

您真正需要的是修改堆栈和链接注册,以便当中断上下文退出时 ,它“返回”到main() ,而不是从那里返回。 这是一项艰巨的任务,可能需要一些汇编代码或编译器内部函数。

您必须意识到,硬件将不会恢复到其重置状态。 您可能至少需要禁用所有中断,以防止在系统重新初始化时发生中断。

此外,如果您跳转到main() ,则不会重新初始化标准库; 而不是重置向量。 特别是,任何当前分配的动态内存都将立即泄漏掉并变得无法使用。 实际上, 所有 C运行时环境初始化都将被跳过-例如在static数据和全局数据中保留其最后状态,而不是应用正确的初始化。

简而言之,这是危险的,容易出错的,针对特定目标的,并且从根本上来说是不良的实践。 要使它正常工作,您要做的大多数事情都已经在调用main() 之前执行的启动代码中完成了,因此调用它要简单得多。 这与强制进行真正的复位(通过看门狗或AICR)之间的区别在于,片上外围状态保持不变(除了在启动中明确进行的任何初始化)。 以我的经验,如果您使用更复杂的外围设备(例如USB),则很难安全地重启系统而不进行真正的重置(或者至少很难确定如何安全地进行该操作),并且几乎不值得付出任何努力。

通过调用main()进行重置是错误的 链接器和C运行时插入的main前面有一些代码,您可以通过这种软复位跳过这些代码。

而是调用NVIC_SystemReset()或启用IWDG和while(1){}进行重置。
HAL应该具有看门狗计时器的示例文件。

维护SRAM。 链接脚本未初始化的任何值仍将存在。

如果不重置堆栈并设置初始值,则从代码的任何位置调用Main()是一个错误的主意。

中断向量中始终有一个初始化函数(实际上调用Main() ),通常可以通过调用NVIC_SystemReset(void)函数来触发此函数,请确保启用此中断,以使其可以软件触发。

据我所知,当进入内部并中断代码时,其他中断被禁止了,我在考虑两种不同的选择:

  • 在中断内部启用中断并调用函数NVIC_SystemReset(void)
  • 修改堆栈并推动函数NVIC_SystemReset(void)的方向,以便当您退出中断时可以执行它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM