[英]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.