记录下以前碰到的问题,免得忘了。
之前项目,STM32F407一使用浮点数就进入hardfault,最开始是在snprintf函数中出现该问题,当时查的方向是snprintf函数,后来发现直接使用浮点数也会出现问题,到此为止确定为浮点数引起的问题。
确定方向后,先确认了STM32的FPU是否开启,查找了对应的浮点数开启的预定义,__FPU_PRESENT 、__FPU_USED 均默认已开启,魔术棒中Target中的Floating Point Hardware也已经启用,到现在为止暂时想不到浮点数相关的了。
虽然想不到还有什么能影响FPU,但是问题还在,没办法只能各种百度,终于在某论坛的某不起眼角落发言中找到了一个可能的问题。
大概来说就是CM4内核带有lazy-stacking功能,这功能大家可以自行百度,大概就是在下面的情况下,会跳过对浮点寄存器组的入栈操作(仅预留浮点寄存器组S0~S15和FPSCR的存储空间),以避免中断延迟的增加:
a.中断处理函数不使用FPU;
b.被中断的程序未曾用到FPU;
该功能默认开启,如果不关闭会影响FPU使用,具体的关闭方式正点原子的STM32F429教程提供了关闭方式,即在启动函数将以下代码修改:
修改前:
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
修改后:
LDR R0, =SystemInit
BLX R0
;要使用FPU就需要加上这段代码,作用是关闭CM4的lazy stacking功能
;加上之后就可以使用snprintf和printf打印浮点数,以及直接使用浮点数
IF {FPU} != "SoftVFP"
LDR.W R0,=0xE000ED88
LDR R1,[R0]
ORR R1, R1,#(0xF<<20)
STR R1,[R0]
DSB
LDR.W R0,=0xE000EF34
LDR R1,[R0]
AND R1,#(0x3FFFFFFF)
STR R1,[R0]
ISB
ENDIF
LDR R0, =__main
BX R0
ENDP
加上这部分就可以正常的使用浮点数了。