如何使用 GDB、OpenOCD 和 arm-none-eabi-gcc 将调试消息打印到带有 STM32 发现板的 gdb 控制台?

电器工程 调试 swd openocd 皮质-m0 数据库
2022-01-30 00:56:24

我正在使用 OpenOCD、arm-none-eabi-gcc 和 gdb 对 STM32 Cortex M0 发现板 (32F0308DISCOVERY) 进行编程。我想知道是否有任何直接的方法可以通过 SWD 记录调试消息。我已经阅读了有关半主机选项的信息,但这似乎需要引入 newlib 或其他大型库。(只有 64k 闪存可用。)有没有更轻量级的方式通过 SWD 记录文本,或者使用 UART 是唯一实用的选择?

1个回答

感谢您的指点,markt 和 chris-stratton。事实证明,半主机选项非常简单。我设法找到了几个可以将消息发送到 OpenOCD 控制台的简单日志记录例程的来源。我会将它们发布在这里,因为(i)它们需要进行一些修改才能工作,并且(ii)我认为对于刚起步的人来说,很难找到这些信息。

首先,这里的 D 代码很容易适应提供以下 C 函数:

void send_command(int command, void *message)
{
   asm("mov r0, %[cmd];"
       "mov r1, %[msg];"
       "bkpt #0xAB"
         :
         : [cmd] "r" (command), [msg] "r" (message)
         : "r0", "r1", "memory");
}

调用 send_command 将字符串写入 OpenOCD 控制台的示例:

const char s[] = "Hello world\n";
uint32_t m[] = { 2/*stderr*/, (uint32_t)s, sizeof(s)/sizeof(char) - 1 };
send_command(0x05/* some interrupt ID */, m);

其次,这里的评论中给出的 putChar 函数工作正常,除了我必须在 0x03 之前添加一个“#”:

void put_char(char c)
{
    asm (
    "mov r0, #0x03\n"   /* SYS_WRITEC */
    "mov r1, %[msg]\n"
    "bkpt #0xAB\n"
    :
    : [msg] "r" (&c)
    : "r0", "r1"
    );
}

要查看这些函数的输出,我首先启动 OpenOCD,然后使用 arm-none-eabi-gdb 进行连接,如下所示:

target remote localhost:3333
monitor arm semihosting enable
monitor reset halt
load code.elf
continue

请注意,消息显示在 OpenOCD 进程的标准输出上,而不是 GDB 控制台上。