Arm stm32-中断句柄

Arm stm32-中断句柄,arm,embedded,interrupt,stm32,interrupt-handling,Arm,Embedded,Interrupt,Stm32,Interrupt Handling,在外部中断函数中,我想通过调用main函数来重置。但之后,若我有一个新的中断触发器,MCU认为它在中断函数中处理,它不再调用中断函数。我的解决方案是什么?(在我的项目中,我不允许调用软重置函数)在任何情况下调用main()都是一个坏主意,正如您所发现的,从中断处理程序调用它确实是一个坏主意 您真正需要的是修改堆栈和链接寄存器,以便当中断上下文退出时,它“返回”到main(),而不是从哪里来。这是一项非常重要的任务,可能需要一些汇编代码或编译器内部函数 您必须意识到硬件不会恢复到其重置状态;您可能

在外部中断函数中,我想通过调用main函数来重置。但之后,若我有一个新的中断触发器,MCU认为它在中断函数中处理,它不再调用中断函数。我的解决方案是什么?(在我的项目中,我不允许调用软重置函数)

在任何情况下调用
main()
都是一个坏主意,正如您所发现的,从中断处理程序调用它确实是一个坏主意

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

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

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

简言之,它是危险的、容易出错的、特定于目标的,而且从根本上说是糟糕的实践。在调用
main()。这与强制真正复位(通过看门狗或AICR)之间的区别在于,片上外围设备状态保持不变(除了启动时明确进行的任何初始化)。根据我的经验,如果您使用的是更复杂的外围设备,如USB,则在没有真正重置的情况下安全地重新启动系统是很难安全实现的(或者至少很难确定如何安全地执行),也不值得付出努力。

无论如何调用
main()
都是一个坏主意,正如您所发现的,从中断处理程序调用它是一个非常糟糕的主意

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

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

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

简言之,它是危险的、容易出错的、特定于目标的,而且从根本上说是糟糕的实践。在调用
main()。这与强制真正复位(通过看门狗或AICR)之间的区别在于,片上外围设备状态保持不变(除了启动时明确进行的任何初始化)。根据我的经验,如果您使用的是更复杂的外围设备(如USB),则在没有真正重置的情况下安全地重新启动系统是很难安全实现的(或者至少很难确定如何安全地执行),也不值得付出努力。

。链接器和C运行时插入的main前面有一些代码,您可以通过这种软重置跳过这些代码

相反,调用
NVIC\u SystemReset()
或在(1){}
重置时启用IWDG和

HAL应该有看门狗定时器的示例文件

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

。链接器和C运行时插入的main前面有一些代码,您可以通过这种软重置跳过这些代码

相反,调用
NVIC\u SystemReset()
或在(1){}
重置时启用IWDG和

HAL应该有看门狗定时器的示例文件

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

如果不重置堆栈并设置初始值,则从代码的任何点调用
Main()
都是错误的想法

中断向量中始终有一个初始化函数(实际上调用
Main()
),通常可以通过调用函数
NVIC\u SystemReset(void)
来触发此函数,请确保启用此中断,以便软件触发它

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

  • 启用中断内的中断,并调用函数
    NVIC\u SystemReset(void)
  • 修改堆栈并推动函数的方向
    NVIC\u SystemReset(void)
    ,以便在中断结束时可以执行该函数
如果不重置堆栈并设置初始值,则从代码的任何点调用
Main()
都是错误的想法

在中断向量中总是有一个初始化函数(实际上调用
Main()
),通常可以通过调用函数
NVIC\u SystemReset(void)
来触发此函数,请确保启用此中断,使其成为软件