参考自:https://blog.csdn.net/jimaofu0494/article/details/102496715
https://blog.csdn.net/gujintong1110/article/details/23038217
很多时候我们要处理的数据,不仅仅是整数和字符串,还有浮点数即小数。在多媒体数据处理方面表现的更多。是不是所有的CPU都支持,浮点运算呢?答案:不是。
今天我在链接一个音频库时,就发现了以下问题:
1、问题描述
在库文件链接阶段报以下错误:
2、原因
该错误表明使用了不正确或不支持的VFP(virtual float point)浮点运算方式。
- 不支持的VFP编译:MCU不支持VFP(hard)计算;
- 不一致的VFP编译:链接的Lib中VFP计算和App中编译VFP计算选项不一致;
3、解决方案
方案1
检查APP的编译选项 CFLAGS
的VFP的计算类型:
FABI := hard //这里把hard改为softfp
CFLAGS += -mfloat-abi=$(FABI)
方案2
更换编译器版本。
方案3
重编译Lib库,CFLAGS
中添加或修改-mfloat-abi=hard
(须和APP中编译选项一致)。
4、实例
环境:
工具链:arm-melis-eabi-
MCU: Cortex-A7-SMP
libmediainfo.a编译中未指明VFP运算方式,默认使用了-mfloat-abi=softfp
APP指明-mfloat-abi=hard
,链接时报错“xxx uses VFP register arguments xxx does not …”
重编译libmediainfo.a库,并在CFLAGS
中指定-mfloat-abi=hard
即可。
重新编译libmediainfo.a库时,指定的CFLAGS
如下所示:
-mfpu=neon-vfpv4 -mtune=cortex-a7 -march=armv7ve -mcpu=cortex-a7 -mfloat-abi=hard
5、知识补充
我们常常听到硬浮点和软浮点,这些到底说的是什么呢?下面我们就来一探究竟吧。在这里我们说的是ARM核浮点运算。
(1) 硬浮点(hard-float)
编译器将代码直接编译成硬件浮点协处理器(浮点运算单元FPU)能识别的指令,这些指令在执行的时候ARM核直接把它转给协处理器执行。FPU 通常有一套额外的寄存器来完成浮点参数传递和运算。使用实际的硬件浮点运算单元(FPU)会带来性能的提升。
(2) 软浮点(soft-float)
编译器把浮点运算转成浮点运算的函数调用和库函数调用,没有FPU的指令调用,也没有浮点寄存器的参数传递。浮点参数的传递也是通过ARM寄存器或者堆栈完成。现在的Linux系统默认编译选择使用hard-float,如果系统没有任何浮点处理器单元,这就会产生非法指令和异常。
因而一般的系统镜像都采用软浮点以兼容没有VFP的处理器。
用一句话总结,软浮点是通过浮点库去实现浮点运算的,效率低;硬浮点是通过浮点运算单元(FPU)来完成的,效率高。
5.1、使用浮点库实现浮点运算(soft-float)
例如:我想实现两个浮点数相加,代码如下:
使用GNU ARM编译器翻译成的部分汇编代码如下: