我在NUCLEO_L432KC上使用MBed OS和MBed CLI进行编译、flash和测试。使用OpenOCD和gdb来调试。MBed有自己的GreenTea测试自动化工具,用于嵌入式硬件的单元测试,它使用了utest和Unity测试框架。
当我使用GreenTea来单元测试这个功能时。
float Piano::midiNumToFrequency(uint8_t m)
{
float exp = (m - 69.0f) / 12.0f;
return pow(2, exp);
}
我得到了一个DeepSleepLock下溢的错误。
[1589410046.26][CONN][RXD] ++ MbedOS错误信息 ++ [1589410046.30][CONN][RXD] 错误状态。0x80040124 代码:292 292 模块:[1589410046.30][CONN][RXD] ++ [1589410046.30][CONN][RXD] 错误状态:0x80040124 代码:292 4 [1589410046.35][CONN][RXD] 错误信息。DeepSleepLock underflow (< 0) [1589410046.37][CONN][RXD] 位置:1: 0x8003B09 [1589410046.40][CONN][RXD] 文件:mbed_power_mgmt.c+197 [1589410046.43][CONN][RXD] 错误值:0xFFFF [1589410046.53][CONN][RXD] 当前线程:main Id: 0x20001200 入口:0x80044A7 0x80044A7 StackSize: 0x1000 StackMem: 0x20001C18 SP: 0x2000FF04 [1589410046.62][CONN][RXD] 更多信息,请访问。 https:/mbed.comserror?error=0x80040124&tgt=NUCLEO_L432KC。 [1589410046.64][CONN][RXD] - MbedOS Error Info ---------。
然而当我把功能改成这样。
float Piano::midiNumToFrequency(uint8_t m)
{
float exp = (m - 69.0f);
return pow(2, exp);
}
它的工作和测试都很好。
MBed有一个错误状态解码器 此处 其中说
使用报告的 "位置 "来找出导致错误的位置的地址,或者尝试在启用MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED配置的情况下构建一个非release版本,以捕获这个错误起源的文件名和行号。
当我启用MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED时,它说位置在mbed_power_mgmt.c第197行,这是functoin。
/** Send the microcontroller to sleep
*
* @note This function can be a noop if not implemented by the platform.
* @note This function will be a noop in debug mode (debug build profile when MBED_DEBUG is defined).
* @note This function will be a noop if the following conditions are met:
* - The RTOS is present
* - The processor turn off the Systick clock during sleep
* - The target does not implement tickless mode
*
* The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
* system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
* dynamic power used by the processor, memory systems and buses. The processor, peripheral and
* memory state are maintained, and the peripherals continue to work and can generate interrupts.
*
* The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
*
* @note
* The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
* Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
* able to access the LocalFileSystem
*/
static inline void sleep(void)
{
#if DEVICE_SLEEP
#if (MBED_CONF_RTOS_PRESENT == 0) || (DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP == 0) || defined(MBED_TICKLESS)
sleep_manager_sleep_auto();
#endif /* (MBED_CONF_RTOS_PRESENT == 0) || (DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP == 0) || defined(MBED_TICKLESS) */
#endif /* DEVICE_SLEEP */
}
有沒有辦法知道為什麼會發生這種情況,或者如何進一步解決問題?
这个部分。
StackSize: 0x1000
StackMem: 0x20001C18
SP: 0x2000FF04
说明堆栈指针已经不在任务自己的堆栈中了。
仅从发布的代码中无法真正确定原因,但报告的位置是irellevant的,当一个函数从损坏的堆栈中弹出返回地址或使用损坏的堆栈指针时,程序-计数器可能会在任何地方结束,也可能无处可去。
例如,有可能是你的测试线程的堆栈分配不足,溢出破坏了其他线程的堆栈或TCB,然后崩溃。这种行为可能会导致你看到的那种错误,其中指示的代码与错误的来源无关。 然而,这纯粹是推测,还有其他错误机制,如缓冲区超限,可能会导致类似的非确定性行为。
最关键的一点是,修改这个函数似乎影响了结果,但这并不意味着这个函数本身有问题。