簡體   English   中英

gnu arm cortex m4上的C ++異常處理程序,帶有freertos

[英]C++ exception handler on gnu arm cortex m4 with freertos

更新2016-12此行為現​​在還有一個最小的示例: https//community.nxp.com/message/862676


我正在使用ARM Cortex M4和freertos使用freescales自由Kinetis IDE(gnu arm工具鏈)。 問題是

try {
    throw 4; // old scenario also not working: throw std::runtime_error("wut");
} catch (...) {
}

在try處理程序之后導致暫停的CPU和代碼,或者在catch處理程序中(當添加一些代碼時)不會執行。

可以在這里找到匯編: https//gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0

我認為這會導致SVC中斷,我很抱歉我弄錯了,Freertos欺騙了我,因為當我扔東西時它會在DefaultISR中停止。

throw indeeds跳轉到__cxa_throw然后從那里___Unwind_RaiseException __gnu_Unwind_RaiseException __cxa_begin_catch> <_ZSt9terminatev>所以它看起來像是調用了std::terminate ,但是catch all塊不應該允許這個。 或者我的假設是錯誤的,這種行為是因為gcc C ++運行時異常支持是一個總是調用終止的存根?!

更新2016-09 :因為我看到rand()嘗試使用malloc(),我還定義了一個工作的malloc()/ freeRTOS函數和etvoilà:__ cxa_allocate_exception使用malloc(我想知道工具鏈是如何期望我處理bad_alloc的情況)。 所以現在,它仍然崩潰,但在異常分配后(我認為):執行路徑是:

(throwing function after exception allocation)
__cxa_throw
   ...                        //(some intructions in __cxa_throw)
   __cxa_begin_catch  //I guess something went wrong here
    _ZSt9terminatev // Immediately after __cxa_begin_catch
        _ZN10__cxxabiv111__terminateEPFvvE:
         00016dfc: push {r3, lr}
         00016dfe: blx r0  //Goes directly to WDOG_EWM_IRQHandler or hard fault handler
         00016e00: bl 0x194ac <abort>

如果你想知道它可能會有所幫助:我的調試器說它的WDOG_EWM_IRQHandler崩潰了,如果我沒有定義hard_fault處理程序和一個自己的默認處理程序。

所以我想在堆棧展開時出現了問題,因為我在_throw的名稱中通過一些帶有“完成堆棧展開”的符號,但是我沒有抓住我在一個對象的析構函數中設置的斷點本應該是清理干凈了。 這似乎激勵__cxa_begin_catch調用中止或其他東西。

(Kinetis Design Studio 3.2.0。使用GNU ARM C / C ++交叉編譯器版本:1.12.1.201502281154用於我們的FRDM-KV31F)

由於錯誤,大多數異常都將執行默認處理程序,因此您需要做的第一件事是確定實際執行的異常。 您可以在下面的頁面中看到“確定哪個異常處理程序正在執行”部分: http//www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

我猜,因為你沒有在你的代碼中使用外圍設備,它將是一個故障處理程序,可能是硬故障。 同一頁面(參見上面的鏈接)也提供了有關調試的說明。

除此之外 - 確保您執行正常的FreeRTOS調試,例如確保您定義了configASSERT(),並且您已經進行了堆棧溢出檢查。 有關這些主題的信息,請訪問此頁面: http//www.freertos.org/FAQHelp.html

從RTOS方面來看,C ++異常只是一個美化的跳躍。 只要它們從您的代碼的一個位跳到另一個,它們就不會干擾RTOS。 所以你可以寫一個try { } catch(std::exception) { }

沒有 C ++處理程序時,當您的C ++代碼停止運行時,RTOS確實必須介入。

在freescales Kinetis中成功創建一個具有默認設置的空白項目,並在nxp社區中提出同樣的問題后 ,恩智浦工程師Alice_Yang(假設通過NXP徽章)告訴我答案:

默認情況下,新項目鏈接到newlib-nano,禁用異常支持。

與newlib-nano一起構建的libstdc ++禁用了異常處理。

所以解決方案是簡單地鏈接到newlib。 這可以通過簡單地刪除“其他鏈接器標志”中的“-specs = nano.specs”行來完成,並確保也禁用添加相同選項的復選框。 然后一切都按預期工作。 只有代碼在ROM /文本大小上增加了27 kB,在RAM /數據中增加了2kB。 在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM