【发布时间】:2020-12-22 11:01:28
【问题描述】:
我已经使用 C++ 编写了一个在 ARM Cortex-M (STM32F0) 上运行的项目,但是我在将定义的缓冲区作为类成员访问时遇到了一些问题,尽管我通过将它们定义为全局变量来解决了这个问题。
但现在我完全被这个新问题困住了,我不知道该怎么办。
我有一个代码可以解锁闪存并在其中写入内容并关闭它。如果我在 C 文件中实现它并通过 C 特性运行它(从 main.c 调用),它会完美运行。但是通过 C++ 文件(无论是在 C 还是 C++ 源文件中编写)调用它都会抛出一个 HardFault 异常。
static uint32_t waitForLastOperation(uint32_t msDelay)
{
while (READ_BIT(FLASH->SR, FLASH_SR_BSY) && msDelay)
{
LL_mDelay(1);
msDelay--;
}
/* Check FLASH End of Operation flag */
if (READ_BIT((FLASH->SR), (FLASH_SR_EOP)))
{
/* Clear FLASH End of Operation pending bit */
(FLASH->SR) = (FLASH_SR_EOP);
}
if (READ_BIT((FLASH->SR),
(FLASH_SR_WRPERR)) || READ_BIT((FLASH->SR), (FLASH_SR_PGERR)))
{
FLASH->SR = 0U;
return 0;
}
/* There is no error flag set */
return 1;
}
uint32_t programHalfWord(uint16_t data, uint32_t address)
{
uint32_t status;
/* Proceed to program the new data */
SET_BIT(FLASH->CR, FLASH_CR_PG);
/* Write data in the address */
*(__IO uint16_t*) address = data;
/* Wait for last operation to be completed */
status = waitForLastOperation(FLASH_TIMEOUT);
if (READ_BIT(FLASH->SR, FLASH_SR_EOP))
FLASH->SR = FLASH_SR_EOP;
/* If the program operation is completed, disable the PG Bit */
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
return status;
}
uint32_t flash_unlock()
{
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) == RESET)
return 1;
/* Authorize the FLASH Registers access */
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
/* Verify Flash is unlocked */
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
return 0;
return 1;
}
这就是我使用它的方式:
if(flash_unlock())
{
programHalfWord(0x11, 0x8007C00);
}
在执行*(__IO uint16_t*) address = data;之后立即抛出异常。
闪存在这个地址被擦除,地址对齐(它实际上是一个扇区的开始)。我检查了一切以确保闪存已解锁,但似乎用 C++ 编译的代码有些问题。
我正在使用 arm-none-eabi-gcc 和 arm-none-eabi-g++ 来编译我的代码。
提前致谢
更新:
这是与 g++ 编译器一起使用的标志列表:
-mcpu=cortex-m0 -std=gnu++14 -g3 -DSTM32F030x6 -DHSE_STARTUP_TIMEOUT=100 -DLSE_STARTUP_TIMEOUT=5000 -DDEBUG -DLSE_VALUE=32768 -DDATA_CACHE_ENABLE=0 -DINSTRUCTION_CACHE_ENABLE=0 -DVDD_VALUE=3300 -DLSI_VALUE=40000 -DHSI_VALUE=8000000 -DUSE_FULL_LL_DRIVER -DPREFETCH_ENABLE=1 -DHSE_VALUE=2000000 -c -I../app/Inc -I../Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I../app/Driver -Og -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-threadsafe-statics -fno-use-cxa-atexit -Wall -fno-short-enums -fstack-usage --specs=nano.specs -mfloat-abi=soft -mthumb
这是给 gcc 的:
-mcpu=cortex-m0 -std=gnu11 -g3 -DSTM32F030x6 -DHSE_STARTUP_TIMEOUT=100 -DLSE_STARTUP_TIMEOUT=5000 -DDEBUG -DLSE_VALUE=32768 -DDATA_CACHE_ENABLE=0 -DINSTRUCTION_CACHE_ENABLE=0 -DVDD_VALUE=3300 -DLSI_VALUE=40000 -DHSI_VALUE=8000000 -DUSE_FULL_LL_DRIVER -DPREFETCH_ENABLE=1 -DHSE_VALUE=2000000 -c -I../app/Inc -I../Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I../app/Driver -Og -ffunction-sections -fdata-sections -Wall -fno-short-enums -fstack-usage --specs=nano.specs -mfloat-abi=soft -mthumb
和 g++ 链接器:
-mcpu=cortex-m0 -T"./STM32F030K6TX_FLASH.ld" -Wl,-Map="${ProjName}.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
【问题讨论】:
-
如果相同的代码适用于 gcc 而不是 g++,这可能是由于您的编译方式不同(传递的选项?)或其他代码(RTOS 在不兼容 C++ 的项目中编译? )。你使用 STL 吗? C++ 在 STL 中具有高级机制(异常、构造函数/析构函数中的分配器等)可能不适合微控制器
-
您是否尝试过在程序集中调试 HardFault?通常这些类型的错误很难调试,您可以在此处阅读更多相关信息freertos.org/…,如果您按照步骤操作,您可以在解散 pc 寄存器后看到确切的行(在 c 的汇编和调用它的行中),此外,如果错误是由 impressise 错误引起的,您需要禁用所有 impresice 代码,这样您的代码运行速度会变慢,但它会帮助您找到错误。
-
@Clonk Checkout 更新我已经包含了标志,而且我没有在这个项目中使用 freeRTOS,并且使用的每个机制对 MCU 都是安全的,所以没有例外,alloc 和 const/destr用过。
-
您是否启用了 MemManage Exception?尝试启用它并查看会发生什么,也许 t 会升级为硬故障。此外,尝试使用 -O0 进行编译以消除任何优化
-
您使用标准外设库吗?或者像
_IO和READ_BIT这样的宏定义在哪里?