DeepSleepLock在执行pow(2, ((m - 69.0f) 12.0f))时出现溢出错误 - MBed OS

问题描述 投票:0回答:1

我在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 */
}

有沒有辦法知道為什麼會發生這種情況,或者如何進一步解決問題?

embedded mbed utest unity-test-framework
1个回答
0
投票

这个部分。

StackSize: 0x1000 
StackMem: 0x20001C18 
SP: 0x2000FF04

说明堆栈指针已经不在任务自己的堆栈中了。

仅从发布的代码中无法真正确定原因,但报告的位置是irellevant的,当一个函数从损坏的堆栈中弹出返回地址或使用损坏的堆栈指针时,程序-计数器可能会在任何地方结束,也可能无处可去。

例如,有可能是你的测试线程的堆栈分配不足,溢出破坏了其他线程的堆栈或TCB,然后崩溃。这种行为可能会导致你看到的那种错误,其中指示的代码与错误的来源无关。 然而,这纯粹是推测,还有其他错误机制,如缓冲区超限,可能会导致类似的非确定性行为。

最关键的一点是,修改这个函数似乎影响了结果,但这并不意味着这个函数本身有问题。

© www.soinside.com 2019 - 2024. All rights reserved.