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

    文章

    16977

    浏览量

    350214
  • 恩智浦
    +关注

    关注

    14

    文章

    5825

    浏览量

    106590

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

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

收藏 人收藏

    评论

    相关推荐

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

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

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

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

    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 8306次阅读
    一文带你秒懂IEEE 754<b class='flag-5'>浮点</b>数

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

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

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

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

    stm32f407浮点运算速度

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

    modbus浮点数怎么读取

    Modbus是一种通信协议,常用于工业自动化系统中的设备之间的通信。它支持多种数据类型,包括整数、浮点数、字符串等。浮点数在工业领域中广泛应用,因此了解如何读取和处理Modbus浮点数是非
    的头像 发表于 12-28 14:38 5805次阅读

    浮点LMS算法的FPGA实现

    引言 LMS(最小均方)算法因其收敛速度快及算法实现简单等特点在自适应滤波器、自适应天线阵技术等领域得到了十分广泛的应用。为了发挥算法的最佳性能,必须采用具有大动态范围及运算精度的浮点运算,而浮点
    的头像 发表于 12-21 16:40 719次阅读

    单精度和双精度浮点数的区别

    单精度和双精度是计算机中表示浮点数的两种不同的精度。在计算机中,浮点数用来表示带有小数部分的实数,而单精度和双精度用来表示浮点数的精确程度不同。在以下文章中,我将详细介绍单精度和双精度浮点
    的头像 发表于 12-15 10:25 5222次阅读

    单精度和双精度浮点数的区别

    在计算机科学和数值计算中,浮点数是一种用于表示实数的数据类型。浮点数有两种精度级别:单精度和双精度。这两种精度级别在表示范围、精度和存储空间等方面都有所不同。本文将详细介绍单精度和双精度浮点数的区别
    的头像 发表于 12-13 10:55 1w次阅读

    圆形连接器选型:几个容易让人“困惑”的术语

    圆形连接器选型:几个容易让人“困惑”的术语
    的头像 发表于 12-06 18:11 700次阅读
    圆形连接器选型:几个容易让人“<b class='flag-5'>困惑</b>”的术语

    python怎么把浮点型转为int

    在Python编程语言中,转换数据类型是一项重要的操作。当我们需要将浮点型数据转换为整型数据时,可以使用int()函数实现。本文将详细介绍Python中的类型转换,并提供了具体的代码示例,帮助读者
    的头像 发表于 11-23 14:56 1888次阅读