工具链更新后浮点数 sprintf() 上的硬故障

问题描述

我有一个开源项目 (https://github.com/WhiteFossa/yiff-l),我在其中使用 STM32F103 MCU。

在固件中,我有很多带有浮点参数的 sprintf,例如:

<span>
   <a class="Update" href="{% url 'link' %}">Get Link</a>
</span>

我曾经使用相当老的 arm-none-eabi xpack 很长一段时间(IIRC 是 9.3.1 版本),一切都很好。

然后我不得不重新安装我的软呢帽,当然我有一个更新版本的 arm-none-eabi。 我的项目停止编译,我修复了一些代码,现在它再次编译,但在任何带有浮点数的 sprintf 上都会产生硬错误

如果我排除了 -u _printf-float 链接器标志,那么硬故障就会消失,但当然我的字符串中没有浮点表示。

我很确定问题不在我的代码中,我什至尝试将 sprintf 作为 main() 的第一行,但仍然存在相同的问题。

什么会导致这种奇怪的行为?我该如何调试它? (从未用于调试 ARM 反汇编)。

附言我尝试安装较旧的 arm-none-eabi xpacks,但没有任何运气 - 问题仍然存在。

P.p.s.我尝试使用优化设置/更改版本进行调试,反之亦然,在 section.ld 中设置了 4 倍以上的堆栈 - 一切都没有成功。

任何帮助将不胜感激。

解决方法

看到这段代码我唯一能想到的就是力量的价值是巨大的:

double power = 11111111111111111111111111111111111111111111.2;
char buffer[32];
sprintf(buffer,"Power: %.1fW",power);

printf("%s\n",buffer);

如果不是这样的话,其他地方一定有一些 UB

,

查找硬故障很复杂,而且很多时候可能会令人沮丧。在大多数情况下,我遇到了硬故障,我只是跳到使用一个硬件调试器。我用于 Cortex-M 设备的是 Segger 的 J-Tag Pro。还有其他型号,更便宜,更便宜。

什么会导致这种奇怪的行为?正如您所确定的,当 sprintf 被禁用时,您的问题被掩盖了。我最好的猜测是,这很可能是由输出缓冲区中的缓冲区溢出或有缺陷的库代码引起的。某些 sprintf 实现使用堆内存分配而不检查 NULL 返回。使用 Fee-RTOS 的 BSP 实现需要进行更多调整才能启用动态内存管理。

如果即使使用大缓冲区也出现硬故障,则这可能是由 sprintf 中的内部内存分配引起的。您可以尝试使用其他库。据我所知,newlib-nano 在某些情况下会导致此错误。

在某些情况下,需要增加调用 sprintf/ snprintf 的任务的堆栈大小和全局堆大小。

我如何调试它? 可能唯一的解决方案是将一个硬件调试器与一个完整的 IDE(如 Eclipse)结合使用。 Here 是一些信息,可为您提供一些指导。 J-Link Edu Mini 硬件调试器的价格相当实惠,但您周围还有更多有用的选项。

我用类似的 CPU(Kinetis K22,从前飞思卡尔现在 NxP)给出的解决方案是创建我自己的浮点到字符串转换函数。它显着提高了性能(不再有 malloc 秒),硬故障错误消失了,我将每个任务的堆大小调整到我真正需要的大小。

,

我终于能够在 https://github.com/mpaland/printf

的帮助下运行我的固件

即我刚刚在我的代码中去掉了 Newlib 的 sprintf()。

enter image description here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...