请教STM32用JLINK V8 SWD输出调试信息到ITM Viewer的问题

2019-12-22 13:41发布

请教各位,我在用STM32F103VBT6 , RVMDK 3.9 ,J-LINK V8的SWD口。
接线为VCC PA13 PA14 GND的四线SWD。程序中重定义了printf的fputc到ITM0.

我想在调试时候,从SWO输出调试信息,参考了一下网上的用ULINK2输出到ITM viewer的例子,自己修改了一下。但是发现用J-LINK 有些问题。
代码如下:
//ITM reg
#define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))
#define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA          0x01000000

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f) {
if (DEMCR & TRCENA) {
while (ITM_Port32(0) == 0);
ITM_Port8(0) = ch;
  }
return(ch);
}
如果在调试器CortexM3 JLINK选项中打开Trace,那么会收到警告信息“Trace仅能从SWO输出,请选择SWD模式”,如果不开trace,那么在ITM viewer中看不到自己的输出信息。
请问有怎么样才可以用printf输出调试信息到ITM viewer
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
44条回答
dhyana
1楼-- · 2019-12-23 13:34
现在的测试结果,用了jlink V7,V8两个编程器。在MDK 4.12下,调试中会在core_cm3.c中的
static __INLINE uint32_t ITM_SendChar (uint32_t ch)
    while (ITM->PORT[0].u32 == 0);
处死循环。
如果不调试,断电上电运行,是正常的。但是都不能在ITM窗口看到调试信息。不明白了。。。
现在我的SWO(PB3)连接到jlink的13脚的。
dr2001
2楼-- · 2019-12-23 14:56
我看了一下,可以用的配置和你是类似的,看看这些是不是正确:

1、写个点LED的代码,确认程序下载到Flash了。(脱开JLink,应该能正常点灯)

2、我的JLink设置:
Debug的Cache Options是一个都没选。因为我要求数据是同步的。这个应该没影响。
Debug的Download Options,两个都有。Verify应该可以不选;Download to Flash应该选上把……要不然咋用?

Trace的Core Clock要按照你初始化代码初始化后的写。
右边一竖列,就是TimeStamp,Trace Events,这个要求MCU集成ETM才好用。STM32好像是没有的,因此最好不要选。
中间的Inst Trace也是什么都不要选的。
ITM按图没问题。

3、代码上,STM32F103C8T6需要DBGMCU_CR = 1 << 5;查一下手册具体的含义。总之就是需要允许一个引脚功能,否则SWO打不出来。

4、用ITM之前,MCU的Core时钟一定要到和你在JLink Trace一样的频率,否则异步数据打出来都是乱的。(类似UART波特率匹配)

写ITM就是这样的语句
while((CM3_ITM_PORT[0] & 0x1) == 0x0)
CM3_ITM_PORT[0] = _C
就足够了。

你参考一下,我用103C8T6在Jlink V7上非常正常。当然开始的时候因为初始化什么的略微折腾了两下。
dr2001
3楼-- · 2019-12-23 16:22
另外补充几句,可能有助于ITM调试。

就我观察到的现象,Keil MDK的Jlink驱动,会根据在Settings页面的设置,在适当的时候设置Cortex M3相关的寄存器。这样用户就不用自行设置相关寄存器,而可以直接使用ITM。
当然,此事不能保证一定在所有的Keil版本和JLink的驱动上复现。

从CM3内核实现上来说,你就视SWO是一个UART就可以了(SWO好象是有两个实现,一个是曼彻斯特编码,一个是UART)。只不过它数据的数据是经过调试接口打包过的。ITM是数据报文的一部分而已。该UART是用CM3 Core的时钟驱动的。
和串口一样,仿真器需要给定一个采样频率,然后你需要在ARM Core设置相应的分频数量。然后允许ITM相关的寄存器,并且让信号从引脚输出。最终ITM方可工作。
ITM输出就是带有Buffer的串口那样。
按串口的调试思路,比较容易搞定。
dhyana
4楼-- · 2019-12-23 16:25
 精彩回答 2  元偷偷看……
lzyr
5楼-- · 2019-12-23 21:05
IAR 可以吗?
dr2001
6楼-- · 2019-12-23 22:20
回复【10楼】dhyana  
-----------------------------------------------------------------------

恭喜。搞定了就好。

Download to Flash,主要是JLink自己能分辨目标是RAM还是Flash,然后调用对应策略搞定。所以Keil的有些选项究竟是什么作用,不太容易弄清楚。不影响使用的话,还是不选比较安全点。

那些Event都会通过ETM打出来调试报文,Keil的调试界面不一定解析了这些东西。或者他的JLink驱动没去解析。谁知道呢。。。
反正一般情况下用不到那些。

具体报文结构在CM3的TRM里边貌似有线索,可能需要看ETM的手册才能知道报文格式。

ITM是单向输出的,如果就是打印调试信息的话,是个很好用的东西。

一周热门 更多>