参考自: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编译器翻译成的部分汇编代码如下:

从图中我们可以知道,默认情况下,编译器使用的是软浮点,图中__aeabi_fadd这个函数是在浮点库中实现。如果想让代码能正常的运行,还需要在连接的时候静态连接一下浮点库。

在这里我们以一个完成的案例来说明一下,软浮点库的使用方法。

start.S:

.global _start

#define USER_MODE 0x10

_start:

@设置CPU为user模式

mov r0,#USER_MODE

msr cpsr_c,r0

@跳到main函数

ldr sp,=0x34000

bl main

stop:

b stop

main.c:

int main()

{

float f1,f2,f3;

f1 = 1.24;

f2 = 1.22;

f3 = f1 + f2;

return 0;

}

Makefile:

LD=arm-none-eabi-ld

OBJDUMP=arm-none-eabi-objdump

RM=rm -rf

CFLAG= -g -c

ASFLAG=-g -c

OBJ=start.o main.o

LDFLAGS= -static -L\

#指定浮点库所在的路径

"C:\Program Files\yagarto\lib\gcc\arm-none-eabi\4.6.2" -lgcc

#设置编译模式

%.o:%.S

$(CC) $(ASFLAG) $< -o $@

%.o:%.c

$(CC) $(CFLAG) $< -o $@

all:$(OBJ)

$(LD) -Ttext=0x20000 $^ -o arm.elf $(LDFLAGS)

$(OBJDUMP) -D arm.elf > arm.dis

clean:

$(RM) *.o arm.dis arm.elf

5.2、使用硬件浮点实现浮点运算(hard-float)

使用硬件浮点的时候,我们需要给编译器传递一些参数,让编译器编译出硬件浮点单元处理器能识别的指令。

(1) -mfpu=name

参数-mfpu就是用来指定要产生那种硬件浮点运算指令,常用的有vfp和neon等。

浮点协处理器指令:

ARM10 and ARM9:

-mfpu=vfp(or vfpv1 or vfpv2)

Cortex-A8:

-mfpu=neon

(2) -mfloat-abi=value

-mfloat-abi=soft 使用这个参数时,其将调用软浮点库(softfloat lib)来支持对浮点的运算,GCC编译器已经有这个库了,一般在libgcc里面。这时根本不会使用任何浮点指令,而是采用常用的指令来模拟浮点运算。如果使用的ARM芯片不支持硬浮点时,可以考虑使用这个参数。在使用这个参数时,链接时一般会出现下面的提示:

undefined reference to '__aeabi_fdiv'

或者类似的提示,主要因为一般情况下链接器没有去主动寻找软浮点库,这时使用将libgcc库加入即可。

-mfloat-abi=softfp

-mfloat-abi=hard

这两个参数都用来产生硬浮点指令,至于产生哪里类型的硬浮点指令,需要由

-mfpu=xxx参数来指令。这两个参数不同的地方是:

-mfloat-abi=softfp生成的代码采用兼容软浮点调用接口(即使用-mfloat-abi=soft时的调用接口),这样带来的好处是:兼容性和灵活性。库可以采用-mfloat-abi=soft编译,而关键的应用程序可以采用-mfloat-abi=softfp来编译。特别是在库由第三方发布的情况下。

-mfloat-abi=hard生成的代码采用硬浮点(FPU)调用接口。这样要求所有库和应用程序必须采用这同一个参数来编译,否则连接时会出现接口不兼容错误。

我们对main.c文件使用硬件浮点重新编译:

翻译成的汇编代码如下:

start.s:

.global _start

#define USER_MODE 0x10

_start:

@ 设置为所有模式都可以访问协处理器,cortex-A8手册 3.2.27

mov r0, #0xfffffff

mcr p15, 0, r0, c1, c0, 2

@ 使能NEON and VFP协处理器,NEON and VFP enable bit.

@ 设置fpexc的30位为1去使能NEON and VFP,cortex-A8 手册 13.4.3

ldr r0, =1<<30

fmxr fpexc, r0

@设置CPU为user模式

mov r0,#USER_MODE

msr cpsr_c,r0

@跳到main函数

ldr sp,=0x34000

bl main

stop:

b stop

main.c:

int main()

{

float f1,f2,f3;

f1 = 1.24;

f2 = 1.22;

f3 = f1 + f2;

return 0;

}

Makefile:

CC=arm-none-eabi-gcc

AS=arm-none-eabi-as

LD=arm-none-eabi-ld

OBJDUMP=arm-none-eabi-objdump

RM=rm -rf

CFLAG=-g -c -mfpu=neon -mfloat-abi=softfp

ASFLAG=-g -c -mfpu=neon -mfloat-abi=softfp

OBJ=start.o main.o

#设置编译模式

%.o:%.S

$(CC) $(ASFLAG) $< -o $@

%.o:%.c

$(CC) $(CFLAG) $< -o $@

all:$(OBJ)

$(LD) -Ttext=0x20000 $^ -o arm.elf

$(OBJDUMP) -D arm.elf > arm.dis

clean:

$(RM) *.o arm.dis arm.elf

linux更改库文件vfp,linux交叉编译的库在链接时提示:xxx uses VFP register arguments xxx does not...相关推荐

  1. linux的八进制文件模式,linux od-输出文件的八进制、十六进制等格式编码的字节...

    博主推荐:获取更多 linux文件内容查看命令 收藏:linux命令大全 od命令用于输出文件的八进制.十六进制或其它格式编码的字节,通常用于显示或查看文件中不能直接显示在终端的字符. 常见的文件为文 ...

  2. xxx uses VFP register arguments xxx does not

    原因 该错误表明使用了不正确或不支持的VFP(virtual float point)浮点运算方式. 1.不支持的VFP编译:MCU不支持VFP(hard)计算: 2.不一致的VFP编译:链接的Lib ...

  3. linux python qt 安装目录,Linux 下QT调用Python库文件 以及Linux 安装Python3.8开发环境 问题...

    最近想运用linux系统下Qt来实现c++ 与python的混合编程,linux系统会自带python2.7版本或者python3.5版本(深度linux). Qt调用python文件需要在pro文件 ...

  4. linux的库文件路径,Linux下的库文件搜索路径

    对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置.连接库位置等),然后生成Makefile以编译程序.可以进入该软件的目录,执行&quo ...

  5. windows下的库文件在linux的使用,Windows、Linux之间传输文件的几种方式

    常见的文件传输协议有ftp.sftp,sftp就是在ftp的基础上对传输的数据进行了加密. ftp速度快,sftp速度略慢但安全性高. ftp默认使用21端口,sftp默认使用22端口. 我使用的是C ...

  6. qt linux 添加库文件路径,linux下qt使用第三方库的那些事

    开发库查看工具:$sudo apt-get install pkg-config 很多时候我们并不知道自己电脑有没有这个库,所以我们可以使用这个工具来查看自己有哪些工具,或者哪些工具没有.同时,qma ...

  7. linux下大文件裁剪,Linux系统裁剪(2)之Linux系统裁剪

    1.这里使用交叉编译的思想,我在Redhat6.4上添加一个硬盘,将该硬盘分区以及安装好MBR之后,再将其挂载到另一个新建的虚拟机上,注意该虚拟机在创建时我只使用了这一个处理好的硬盘. 2.怎么添加新 ...

  8. Linux什么是文件IO,linux中文件IO

    一. linux常用文件IO接口 1.1. 文件描述符 1.1.1. 文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指 ...

  9. linux静默删除文件夹,Linux常用命令10 - unzip

    zip 是最广泛使用的归档文件, 除了linux,windows也是非常的广泛.,支持无损数据压缩. zip 文件是包含一个或多个压缩文件或目录的数据容器. 接下来,我将解释如何使用 unzip 命令 ...

  10. linux 怎么管理文件夹,Linux 是如何管理目录文件?

    Linux 是使用级层式的树状结构来管理文件目录,如下图所示(只列出了部分目录文件): 在 Linux 中,所有的文件和目录都由根目录(/)开始.它是所有目录和文件的源头,然后再一个一个分支下去.所以 ...

最新文章

  1. linux c printf 不能输出
  2. Java与嵌入式数据库SQLite的结合
  3. 文件系统fsd hook (一)原理
  4. ITK:将图像传递给函数
  5. 动态路由和动态路由中的RIP协议
  6. 机器学习实验中的编程技术(part1)--numpy
  7. 基于Hi3516A的H265 IPC LIVE555 开发基本原理
  8. 余承东:华为自研的麒麟A1芯片已经应用在了多款可穿戴产品中
  9. php-有时候你会疑惑的小问题
  10. 查看linux文件目录的大小和文件夹包含的文件数
  11. plc通信程序 c语言,三菱PLC编程口通信C语言源代码(3)
  12. 计算机原理的拼音,微机原理课程,the course of microcomputer principles,音标,读音,翻译,英文例句,英语词典...
  13. ERP如何才能实施成功:ERP成功率为0现象 从具体实施层面剖析
  14. php融云开发文档,融云公众服务
  15. android微信点赞ui,Android中使用PopupWindow 仿微信点赞和评论弹出
  16. 数据库安装时需要更新以前的Visual Studio 2010实例状态失败-----亲测可行
  17. java web开发(一) Java Web开发框架对比
  18. 科技论文的种类_如何快速对科技论文分类
  19. 二进制LDPC码的构造及译码算法
  20. 网盘上传工具Boxifier怎么用?

热门文章

  1. c语言数字转换为字符串补位,String字符串补位
  2. 2019中国国际大数据产业博览会将5月26-29日贵阳举行
  3. supervisor web页面访问
  4. 浅析RTB和RTA(一)
  5. jenkins备份恢复
  6. python爬虫—爬取taptap游戏的评论信息(通过fiddler抓包)
  7. 哦了哦了~,开始切难题~
  8. c# 讯飞语音 sdk
  9. cython使用初步
  10. 【Unity学习】Unity GetCurrentAnimatorStateInfo方法判断动画播放