我尝试使用带有openocd
版本0.10.0+dev-00512-gfd044600
和gdb-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....
答案 0 :(得分:2)
ITM通道可以处理8位,16位和32位数据。
ITM_SendChar()
使用8位(1字节)流,因此每隔一个字节就有1
作为后续数据部分的长度。
对于swo.log
解码,可以使用this post中的perl脚本。
答案 1 :(得分:2)
只需澄清一下,“半主机”和“ SWO”是完全独立的概念。您描述的内容没有使用半主机,因此您可以跳过--specs=rdimon.specs
,initialise_monitor_handles();
和monitor arm semihosting enable
,因为它们与您的问题无关。
半主机是一种让主机系统实现某些系统调用的方法,方法是让目标填充内存中的某些数据结构,然后执行断点。这将触发调试主机(OpenOCD),然后它将从目标内存中读取参数,模拟系统调用,将结果写回到内存中,最后恢复目标。这可以用作stdout
通道,但也可以用作更多通道(stdin
,完整的文件系统仿真等)。缺点是目标在系统调用过程中被暂停,因此该方法非常麻烦。
SWO是轻量级跟踪通道,它可以通过ITM块的32个通道中的任何一个输出任意数据。这可以用作非侵入式stdout
频道。其他类型的数据也可以通过SWO输出进行传输。时间戳记,PC采样,DWT变量访问轨迹,性能计数器等等。这种多路复用需要围绕每种数据类型进行成帧,这就是您在SWO日志文件中看到的额外字节。数据流可以由Swodec之类的实用程序解码。