为什么 PRIx64 打印“lx”而不是 16 个十六进制字符?

Dar*_*anX 2 c hex 32-bit uint64 cortex-m

我们在工作中遇到了一个问题,我们无法使用<inttypes.h>(PRIx64) 中的“可移植”类型来正确打印十六进制格式的 64 位无符号整数。

uint64_t serial = 0x12345678;
usb_printf("Serial: %"PRIx64"\n", serial);
Run Code Online (Sandbox Code Playgroud)

在哪里

void usb_printf(const char *fmt, ...)
{
    char string[512];
    uint16_t string_length = 0;
    va_list va;

    va_start(va, fmt);
    string_length = vsnprintf(string, ARRAY_SIZE(string), fmt, va);
    bsp_usb_cdc_send_buf((uint8_t *)string, string_length);
    va_end(va);
}
Run Code Online (Sandbox Code Playgroud)

给出

> Serial: lx
Run Code Online (Sandbox Code Playgroud)

它在 LPC55S28 (Cortex-M33) 上运行,并-specs=nosys.specs -specs=nano.specs使用 GCC 链接。

通过查看 PRIx64 定义,它似乎被定义为:

#define __INT64 "ll"
#define __PRI64(x) __INT64 __STRINGIFY(x)
#define PRIx64      __PRI64(x)
Run Code Online (Sandbox Code Playgroud)

为什么可PRIx64移植类型定义在此平台上的行为不符合人们的预期?

P__*_*J__ 5

newlib-nano不支持浮点数(需要告诉链接器链接支持),printf也不支持long long数字(并且没有办法添加支持)。

nano.specs如果您想打印long long数字,则不能使用

纳米文档明确指出

     enable-newlib-io-pos-args
     enable-newlib-io-c99-formats
     enable-newlib-io-long-long
     enable-newlib-io-long-double
Run Code Online (Sandbox Code Playgroud)

不支持构建选项。因此,即使使用这些选项重建库也不会添加支持。

结论:

  1. 不要使用 newlib-nano
  2. 编写自己的long long打印函数。

一般说明:当您对微控制器进行编程时,您应该忘记在对大型机器(如 PC 计算机)进行编程时通常使用的许多东西,尤其是malloc样式分配和花哨的printf格式。