0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浮点库应用,你也有困惑吗?

恩智浦MCU加油站 来源:未知 2023-12-21 08:55 次阅读

今天小编想要给大家带来的是最近在调试一个项目时候发现的怪事,同样的函数库在使用不同的IDE时,得到的运行结果竟然是不一致的。相信眼尖的读者朋友已经从标题中猜出一二了,正是因为库中依赖了浮点计算库所导致的问题。那么就请和小编一起,探究下详细的来龙去脉吧!

项目背景

首先再详细描述以下项目背景:我们使用了一个由GCC工具链构建的函数库,编译器选项为-mfloat-abi=hard,即在编译时,使能了硬件浮点单元指令加速。但在我们将该库与Keil项目链接后,发现结果不正确。当然,我们最先怀疑的当然是库编译的有问题啦。但是奇怪的事情发生了,我当我们使用GCC工具链链接编译相同的工程,并运行后,得到了正确的结果。那么可以基本确定,库应该是没有问题的。那么问题出在哪呢?

问题分析

由于小编所拿到的库并不包含调试信息,只能通过一些技术手段进行破解。通过反汇编库代码,我们发现库依赖了一些浮点计算库的C函数,如sqrtf、expf等,为了简便,让我们称之为xxf函数,由于GCC并没有提供其具体实现,因此需要由库的使用者链接这些函数,而经过进一步的debug,我们发现这些函数导致了错误的结果,换句话说,这些函数的返回值是错的。

问题调试

那就有意思了,为了简单起见,让我们先编写一段简单的测试代码来复现这个问题,代码很简单,我们直接定义一个开平方根的函数:

#include "math.h"

float calc_sqrt(float a){

return sqrtf(a);

}

使用gcc工具链对其进行编译:

arm-none-eabi-gcc.exe -mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard test.c -fshort-wchar -c -o test.o

随后,随便找到一个Keil的测试工程,我们这里选择一个Hello_World示例工程,将编译出来的.o文件添加到工程中:

wKgZomWDjhGANp5cAABcyFsEcJc683.png

并在主程序中添加调用代码:

float calc_sqrt(float a)

volatile float a = calc_sqrt(4.0f);

编译链接下载程序,并让程序停在函数调用处:

wKgZomWDjhKAUXnTAADNmNIH8Rw407.png

单步进入calc_sqrt函数内部,到这里,我们可以发现对这些函数的调用顺序是正确的。通过将参数传递给S0(对于float)如下所示,S0中寸的就是待计算的数据4.0f:

wKgZomWDjhKAcUdQAAFHqs3OJMk254.png

wKgZomWDjhKAbZ7dAAA743Nmdr0045.png

看起来好像没有问题,再进一步现在让我们检查由Keil链接的sqrtf函数的汇编实现:

wKgZomWDjhKAF50tAADszXvbpi8487.png

相信大家发现了奇怪的事情了,链接的sqrtf将S0中的值传递给S0,而此时R0的值其实为0,但正如之前所说,浮点值已经由库的代码传递给了S0。因此,由于S0中实际要计算的值被临时替换了,就导致了一个错误的结果。

wKgZomWDjhKAFognAABSVmp7PxU258.png

这里要强调一下,如果在Keil中直接调用sqrtf时候,或是使用keil编译器所编译出来的.o文件,Keil运行时库会使用“__hardfp_sqrtf”作为sqrtf的混淆名称:

wKgZomWDjhKAZvr5AACqgxPX2Ic445.png

而因为我们所使用库来自GCC工具链,因此Keil并不会对其进行替换,而是会将C库中叫做sqrtf的函数直接链接进去,而这个函数的默认实现,是使用R0作为参数传递的寄存器。这也就导致,实际要被计算的数丢失,最终导致结果计算错误。

那么怎么解决这个问题,让keil不去链接这个奇怪的sqrtf呢,这就要用到Keil的一个小技巧了:

float $Sub$$sqrtf(float a){

return __builtin_sqrtf(a);

}

这样一来,调用sqrtf函数的地方,就会编程对$Sub$$sqrtf的调用:

wKgZomWDjhKAMFbbAAE1zkGftN4411.png

wKgZomWDjhOACcEzAAIb8mxu1DA400.png

而结果也变为正确的结果2.0了:

wKgZomWDjhOAJ6olAABTCNVByDY135.png

当然,大家可能会想啊,那我开了gcc优化之后,是不是就可以自动展开sqrtf了呢?让我们来看看:

arm-none-eabi-gcc.exe -mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard test.c -fshort-wchar -c -o3 -o test.o

代码并没有变化:

wKgZomWDjhOAE65GAAEt3Qti-14440.png

结论

小编想用这个例子和大家说明下,在涉及到跨工具链开发时,一定要注意浮点库的使用或依赖问题,由于不同编译器对于浮点运算的实现可能有些许不同,会导致意想不到的奇怪问题出现。最好的方案,还是根据不同的工具链都构建一个专属的库来使用。

END

更多恩智浦AI-IoT市场和产品信息,邀您同时关注“NXP客栈”微信公众号

wKgZomWDjhOACI5YAABCdkRE230322.jpg      

NXP客栈


恩智浦致力于打造安全的连接和基础设施解决方案,为智慧生活保驾护航。

长按二维码,关注我们

恩智浦MCU加油站


这是由恩智浦官方运营的公众号,着重为您推荐恩智浦MCU的产品信息、开发技巧、教程文档、培训课程等内容。

wKgZomWDjhOAHK_FAAATNlPH08Y075.jpg  

长按二维码,关注我们


原文标题:浮点库应用,你也有困惑吗?

文章出处:【微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17162

    浏览量

    351350
  • 恩智浦
    +关注

    关注

    14

    文章

    5861

    浏览量

    107531

原文标题:浮点库应用,你也有困惑吗?

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【RA-Eco-RA4E2-64PIN-V1.0开发板试用】RA4E2的DSP浮点性能的软件浮点测试和硬件浮点测试对比

    , atan,等等基本操作。 当然为了测试出硬件浮点运算性能,这里很有必要在测试一下软件浮点运算能力,方便做个测试对比,怎么做软件浮点运算呢? 这个可以使用开源Qfplib,这是国外
    发表于 12-30 17:55

    FPGA中的浮点四则运算是什么

    由于定点的四则运算比较简单,如加减法只要注意符号扩展,小数点对齐等问题即可。在本文中,运用在前一节中描述的自定义浮点格式FPGA中数的表示方法(下),完成浮点四则运算的实现过程 1.自定义浮点格式加
    的头像 发表于 11-16 12:51 272次阅读
    FPGA中的<b class='flag-5'>浮点</b>四则运算是什么

    FPGA中浮点四则运算的实现过程

    由于定点的四则运算比较简单,如加减法只要注意符号扩展,小数点对齐等问题即可。在本文中,运用在前一节中描述的自定义浮点格式FPGA中数的表示方法(下),完成浮点四则运算的实现过程 1.自定义浮点格式加
    的头像 发表于 11-16 11:19 454次阅读
    FPGA中<b class='flag-5'>浮点</b>四则运算的实现过程

    【RA-Eco-RA2E1-48PIN-V1.0开发板试用】在M23内核上使用qfplib浮点运算进行浮点运算

    运算。难道由于硬件不支持FPU, 常用的M0/M0+/M23/M3内核就无缘浮点运算了呢?答案是显然不是的。 我们可以移植使用开源的qfplib来实现浮点运算,这样在一些不具备FPU的低性能MCU上
    发表于 11-05 22:07

    【RV32F与RV32D】之单精度和双精度浮点

    和所有其它31个f寄存器一样,是一个可变寄存器。 IEEE 754-2008标准提供了几种浮点运算舍入的方法,这有助于确定误差范围和编写数值。最准确且最常见的舍入模式是舍入到最近的偶数(RNE
    发表于 08-29 12:24

    TMS320C6742定点和浮点DSP数据表

    电子发烧友网站提供《TMS320C6742定点和浮点DSP数据表.pdf》资料免费下载
    发表于 08-07 09:57 0次下载
    TMS320C6742定点和<b class='flag-5'>浮点</b>DSP数据表

    ESP8266_RTOS_SDK如何打印浮点数?

    尝试使用 printf 打印浮点数,例如, 浮点数 d = 1.0; printf("d = %f", d); 但它打印出来: d = 此外,sprintf
    发表于 07-09 06:56

    STM32CubeIDE printf浮点数,浮点数丢失数值的原因?

    1、芯片:STM32F103C8T62、环境:STM32CubeIDE3、问题:printf浮点数,浮点数数值丢失如 float A=25.6666;float B=24.7777;实际打印
    发表于 06-03 07:07

    优秀的Verilog/FPGA开源项目-浮点运算器(FPU)介绍

    浮点运算器(英文:floating point unit,简称FPU)是计算机系统的一部分,它是专门用来进行浮点数运算的(CPU中也叫ALU)。
    的头像 发表于 04-26 11:27 3474次阅读
    优秀的Verilog/FPGA开源项目-<b class='flag-5'>浮点</b>运算器(FPU)介绍

    STM32cubemx的和KEIL的有什么不同?

    STM32cubemx软件有对应各个系列芯片的. 使用cubemx,生成代码框架,比如生成MDK的代码框架。但MDK也有自己的PACK。那么MDK的PACK和CUBEMX的有什么区别,两者时什么关系呢?
    发表于 04-11 06:02

    verilog语音实现浮点运算

    Verilog可以通过使用IEEE标准的浮点数表示来实现浮点运算。下面是一个基本的Verilog模块示例,展示了如何进行加法、乘法和除法等常见的浮点运算操作: module
    发表于 03-25 21:49

    一文带你秒懂IEEE 754浮点

    一、简介1、常见的浮点数表示方式是IEEE754标准,它规定了浮点数的存储格式和运算规则,这个标准定义了两种浮点数表示:单精度和双精度。2、任何一个浮点数的二进制数可以写为:NUM=(
    的头像 发表于 03-18 08:09 8813次阅读
    一文带你秒懂IEEE 754<b class='flag-5'>浮点</b>数

    使用的H7系列MX编写代码后生成静态文件,如何更改静态工程也使用硬件双精度浮点数?

    使用的H7系列MX编写代码后生成静态文件, 在调用该静态文件并编译报错,如下: 然后我查看了静态工程的编译指令: 而APP程序的编译指令: 想请教一下,该如何更改静态工程
    发表于 03-12 06:15

    毫米波雷达半精度浮点存储格式分析

    本文介绍了TC3xx单片机雷达信号处理单元SPU支持的半精度浮点格式,将其和32bit整型数格式进行比较,分析了两者的动态范围及实际处理误差,发现半精度浮点格式是“性价比”较高的存储方式。
    的头像 发表于 02-20 08:26 382次阅读
    毫米波雷达半精度<b class='flag-5'>浮点</b>存储格式分析

    stm32f407浮点运算速度

    支持硬件浮点运算单元(FPU),可以提供快速和高效的浮点运算性能。本文将详细介绍 STM32F407 的浮点运算速度。 浮点运算是很多应用中常用的一种运算类型,特别是对于需要进行较复杂
    的头像 发表于 01-04 10:58 3401次阅读