使用openocd和gdb在STM32L4芯片上通过半主机获取额外的字节

时间:2019-03-11 14:46:46

标签: gdb stm32 openocd

我尝试使用带有openocd版本0.10.0+dev-00512-gfd044600gdb-multiarch的SWO引脚获得一些调试输出。

我用带有标志ARMToolchain_8-2018-q4的{​​{1}}编译了固件,并将函数调用--specs=nosys.specs --specs=nano.specs --specs=rdimon.specs放在了initialise_monitor_handles();中。我的main()看起来像这样:

.gdbinit

我在target extended-remote localhost:3333 monitor reset halt monitor arm semihosting enable monitor tpiu config internal ../bin/swo.log load break main 函数中安装了对ITM_SendChar()的调用,如下所示:

_putchar()

芯片为STM32L432KC,openocd命令为:

void _putchar(char c) { ITM_SendChar(c) };

当我打印“ Test \ r \ n”字符串时,我在openocd -f board/stm32l4discovery.cfg 文件中得到了一些多余的字符(从swo.log输出):

xxd -b swo.log

字符串“ Test \ r \ n”在那里,但有一些多余的垃圾。我该如何摆脱呢?

我现在的解决方法是使用以下方法剪切不可打印的字符:

000032e8: 00000001 01010100 00000001 01100101 00000001 01110011  .T.e.s
000032ee: 00000001 01110100 00000001 00001101 00000001 00001010  .t....

2 个答案:

答案 0 :(得分:2)

ITM通道可以处理8位,16位和32位数据。

ITM_SendChar()使用8位(1字节)流,因此每隔一个字节就有1作为后续数据部分的长度。

对于swo.log解码,可以使用this post中的perl脚本。

答案 1 :(得分:2)

只需澄清一下,“半主机”和“ SWO”是完全独立的概念。您描述的内容没有使用半主机,因此您可以跳过--specs=rdimon.specsinitialise_monitor_handles();monitor arm semihosting enable,因为它们与您的问题无关。

半主机是一种让主机系统实现某些系统调用的方法,方法是让目标填充内存中的某些数据结构,然后执行断点。这将触发调试主机(OpenOCD),然后它将从目标内存中读取参数,模拟系统调用,将结果写回到内存中,最后恢复目标。这可以用作stdout通道,但也可以用作更多通道(stdin,完整的文件系统仿真等)。缺点是目标在系统调用过程中被暂停,因此该方法非常麻烦。

另一方面,

SWO是轻量级跟踪通道,它可以通过ITM块的32个通道中的任何一个输出任意数据。这可以用作非侵入式stdout频道。其他类型的数据也可以通过SWO输出进行传输。时间戳记,PC采样,DWT变量访问轨迹,性能计数器等等。这种多路复用需要围绕每种数据类型进行成帧,这就是您在SWO日志文件中看到的额外字节。数据流可以由Swodec之类的实用程序解码。