簡體   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