snprintf 在显示 %d 或 %u 时崩溃

发布于 2024-12-09 02:07:45 字数 264 浏览 0 评论 0原文

我正在尝试使用 snprintf 将整数打印到字符串中,以便在 ARM 微控制器的 OLED 显示屏上显示。但是,当我使用 %d 或 %u 时,微控制器会锁定并停止执行。 使用 %x 或 %c 效果很好,但输出没有多大用处。

什么可能导致这种行为?不幸的是我无法访问 JTAG 设备进行调试。我使用arm-none-eabi-gcc 进行编译,它全部运行在maple mini 上。

更新

传递值< 10 似乎可以正常工作。

I'm trying to print an integer into a string with snprintf for display on an OLED display from an ARM micro. However, when I use %d or %u the micro locks up and stops executing.
Using %x or %c works fine, but the output isn't much use.

What could cause this behaviour? Unfortunately I don't have access to a JTAG device to debug. I'm using arm-none-eabi-gcc to compile and it's all running on a maple mini.

UPDATE

Passing values < 10 seems to make it work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

箹锭⒈辈孓 2024-12-16 02:07:45

这实际上是我使用的 RTOS 的堆栈大小问题。我猜想 snprintf 调用增加的复杂性使其超出了限制并崩溃了。

感谢所有认真回答这个问题的人!

This actually turned out to be a stack size issue with the RTOS that I was using. I guess the added complexity of the snprintf call was pushing it over the limit and crashing.

Thanks to all who took a crack at answering this!

雪若未夕 2024-12-16 02:07:45

传递值< 10 似乎可以正常工作。

在我看来,这听起来好像你缺少/不起作用的划分例程。 printf/sprintf 通常通过连续除以 10 来打印十进制数字。对于小于 10 的数字,不需要除法,这可能就是它不起作用的原因。

要进行检查,请创建一个除以两个变量的函数(除以常量通常被编译器优化为乘法)。例如:

int t()
{
  volatile int a, b; // use volatile to prevent compiler optimizations
  a = 123;
  b = 10;
  return a/b;
};

另外,检查您的构建日志中是否有链接警告。

Passing values < 10 seems to make it work.

This sounds to me as if you have a missing/non-working divide routine. printf/sprintf usually prints decimal numbers by successively dividing them by 10. For numbers less than 10 the division is not necessary and that's probably why it doesn't work.

To check, make a function which divides two variables (dividing by a constant is usually optimized into multiplication by the compiler). E.g.:

int t()
{
  volatile int a, b; // use volatile to prevent compiler optimizations
  a = 123;
  b = 10;
  return a/b;
};

Also, check your build log for link warnings.

梦里的微风 2024-12-16 02:07:45

它不可能是类型错误,因为 %x%u 都指定了相同的类型。所以这一定是 snprintf 本身的问题。两者之间唯一的主要区别是 %u 必须除以整数并计算余数,而 %x 可以通过移位和掩码来完成。

您的 C 库可能是针对与您正在使用的不同类型的 ARM 处理器编译的,并且它可能使用非法指令来计算商或余数。

确保您正在为 Cortex M3 编译库。例如,

gcc -mcpu=cortex-m3 ...

It can't be a type error since %x and %u both specify the same types. So it has to be a problem in snprintf itself. The only major difference between the two is that %u has to divide integers and compute the remainder, whereas %x can get by with shifts and masks.

It is possible that your C library was compiled for a different variety of ARM processor than you are using, and perhaps it is using an illegal instruction to compute a quotient or remainder.

Make sure you are compiling your library for Cortex M3. E.g.,

gcc -mcpu=cortex-m3 ...
最佳男配角 2024-12-16 02:07:45

您有范围内的原型吗? snprintf() 是一个可变参数函数,调用可变参数可能会涉及一些技巧来在函数期望的位置获取参数。

另外:调用可变参数函数时始终使用正确的类型。 (“%”后面的那个是 snprintf() 期望在某处找到的类型,“某处”甚至可能取决于类型。一切都可以......)在您的情况下:“%X”需要一个无符号整数。通过在函数调用中强制转换参数或使用“unsigned int swinglow;”将其交给她。定义它时。无论如何,负频率或计数没有意义。

Do you have a prototype in scope ? snprintf() is a varargs function, and calling a varargs may involve some trickery to get the arguments at the place where the function expects them.

Also: always use the proper types when calling a varargs function. (the one after the '%' is the type that snprintf() expects to find somewhere, 'somewhere' may even depend on the type. Anything goes...) in your case : "%X" expects an unsigned int. Give it to her, either by casting the parameter in the function call, or by using "unsigned int sweeplow;" when defining it. Negative frequencies or counts make no sense anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文