繁体   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