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