本帖最后由 大树树 于 2018-8-23 19:18 编辑 项目采用F767芯片,使用了UCOSIII系统,实际运行中出现浮点计算数据异常的问题,后仔细排查发现输入值正常的情况下,计算结果出现了特别大的值。 后来将FPU关闭之后计算数值一切正常。 计算代码示意如下,其他值都正常,结果错的离谱。
以下是几处配置的地方,不知有没有问题 1、option->target 选项中选择了use single precision 2、c/c++ 的define 中只添加STM32F767xx,USE_HAL_DRIVER 3、stm32f767xx.h中__FPU_PRESENT 设置为1 所有UCOS的任务都加入了OS_OPT_TASK_SAVE_FP选项,任务堆栈也都设置的很大,基本都是1024的。 没有用arm_math.h中的函数,只用了math.h的函数,按理讲应该只影响效率不影响结果的。 实在是搞不定了,在网上搜了好久也没有找到合理的解释。 现在怀疑两个方面的问题: 1、FPU配置的问题,不知道有没有不合适的地方; 2、UCOS运行会不会影响FPU的结果,没有找到相关的解释。 求大神指点,万分感激~~ |
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
IF {FPU} != "SoftVFP"
; Enable Floating Point Support at reset for FPU
LDR.W R0, =0xE000ED88 ; Load address of CPACR register
LDR R1, [R0] ; Read value at CPACR
ORR R1, R1, #(0xF <<20) ; Set bits 20-23 to enable CP10 and CP11 coprocessors
; Write back the modified CPACR value
STR R1, [R0] ; Wait for store to complete
DSB
; Disable automatic FP register content
; Disable lazy context switch
LDR.W R0, =0xE000EF34 ; Load address to FPCCR register
LDR R1, [R0]
AND R1, R1, #(0x3FFFFFFF) ; Clear the LSPEN and ASPEN bits
STR R1, [R0]
ISB ; Reset pipeline now the FPU is enabled
ENDIF
LDR R0, =__main
BX R0
ENDP
评分
查看全部评分
我认为这个问题的根本原因是OS_CPU_A.ASM这个文件的问题,现在网上所有的这个文件都是用的cortex-m4的,
这个文件包含多个函数用于任务切换,其中包括多个与浮点数寄存器堆栈有关的函数,它只支持single precision,显然stm32f767(cortex-m4)的double precision是不兼容的。
这个文件本应该是官方发布(可惜一直没发),由于本人水平有限,不懂汇编,还请高人参照数据手册实现函数,为民造福
评分
查看全部评分
有没有可能被其他任务打断了。我上次遇到的更奇怪,keil中跑裸机,使用const u16 Val = 64;时这个Val居然会变化。。。然后改成#define Val 64 就没问题,也搞不懂。。而且,上下文定义的const常量,有的变了有的没变。。
评分
查看全部评分
评分
查看全部评分
被打断也有可能,可加了OS_OPT_TASK_SAVE_FP选项不是应该可以保存浮点寄存器值的么,难道这还需要加临界区?
输出结果的变量定义的是float,运算中就算有double,结果也应该是把超出精度部分舍去不是么
昨天调试发现计算的时候关中断就不出错了。
但按道理讲创建任务时候加了OS_OPT_TASK_SAVE_FP选项的,可结果来看好像浮点寄存器出入栈的时候出了问题。
不懂还有什么地方有问题的。
评分
查看全部评分
计算耗时多少啊,关中断计算完再开→_→
这个我看了下是有的,目前没有因为计算死机,就是数据会错误
好的,我试试看,谢谢
q_3*powf(traj_PATH_x,3) + q_4*powf(traj_PATH_x,4)+ q_5 *powf(traj_PATH_x,5);
只算powf的时候就被中断打断了然后切换到了其他地方?
相当于你的操作不是原子性的……?但是理论上来说,及时打断了也能恢复,但是被打断的时候,寄存器是否有被中断函数覆写?
评分
查看全部评分
UCOS按正常来讲应该会将浮点寄存器的值入栈的,但感觉上没有正常入栈导致的问题。