ARM Cortex M4硬故障 - 浮点

时间:2014-11-24 23:17:17

标签: gcc floating-point arm stm32 stm32f4discovery

当我运行我的程序时,它只计算一个正弦波:

for(i = 0; i < ADS1299_SIGNAL_WINDOW; i++){
    TEST[i] = (float32_t)(10.0f * (float32_t)(arm_sin_f32((float32_t)(3.14f * i/ADS1299_SIGNAL_WINDOW))));
}

编译器生成以下行,这会导致硬故障:

800702a:    ed2d 8b04     vpush    {d8-d9}

发生了什么事?作为参考,这是我的编译器标志:

SETTINGS="-g -nostartfiles -mthumb -mthumb-interwork -march=armv7e-m -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -fdata-sections -ffunction-sections -O3 -Wl,-T,../STM32F407VG_FLASH.ld"
DECLARE="-DARM_MATH_CM4 -D__FPU_PRESENT=1 -D__FPU_USED"
....  -larm_cortexM4lf_math

3 个答案:

答案 0 :(得分:3)

问题是您在同一范围内同时执行CPACR启用,某些浮点运算。因为main中的代码使用浮点寄存器,所以编译器(表现良好且尊重ABI)将发出代码以在main的条目下保留这些寄存器。 之前 main中的任何其他代码都会执行。包括写入CAPCR,使其可访问。糟糕。

要避免这种情况,要么在重置处理程序中将条目中的CP启用到main之前(如果您的工具链允许),或者只是在另一个函数中执行所有FP操作,并确保{{1本身不接触任何FP寄存器。

在CPACR写入后确保您具有main同步序列也是明智的(如果您还没有)。否则,您可能仍然可能从管道中已有的任何过时的FP安装中获得错误。

答案 1 :(得分:2)

我认为问题是FPU未启用。我在Keil 4上的Nordic Semiconductors SDK示例遇到了同样的问题。在Keil IDE中标记了FPU启用的复选框,但在SystemInit代码中它是条件编译,如下所示:

void SystemInit(void) {
#if (__FPU_USED == 1)
    SCB->CPACR |= (3UL << 20) | (3UL << 22);
    __DSB();
    __ISB();
#endif
}

但我认为Keil 4 IDE没有将此__FPU_USED设置为1,而在VPUSH指令上我有一个HardFault,因为FPU未启用。

我认为您需要在SystemInit中启用FPU,然后问题就会解决。

答案 2 :(得分:0)

如果使用FPU,堆栈应对齐到8个字节的边界。如果您使用的是RTOS,请检查线程堆栈初始化代码。如果您使用纯裸机运行,请检查堆栈设置的启动代码。