2

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

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
4

3 回答 3

4

问题是您在同一范围内同时启用 CPACR一些浮点运算。因为 in 中的代码main使用浮点寄存器,所以编译器(表现良好并尊重 ABI)将发出代码以在main. 执行任何其他代码之前main。包括对 CAPCR 的写入,这使得它们可以访问。哎呀。

为避免这种情况,请在进入复位处理程序中的 main之前在 CPACR 中启用 FP (如果您的工具链允许),或者只是在另一个函数中执行所有 FP 操作,并确保main其自身不会触及任何 FP 寄存器。

DSB; ISB确保在 CPACR 写入后有一个同步序列也是明智之举(如果您还没有的话) 。否则,您可能仍然会因管道中已经存在的任何陈旧的 FP 指令而出现故障。

于 2014-11-25T01:42:32.817 回答
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,然后问题就会得到解决。

于 2017-04-18T07:55:23.713 回答
0

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

于 2014-11-25T04:49:35.813 回答