通过Cortex-M3 CPU上的printf进行输出调试,停止BKPT指令+关于JTAG和sw端口的混淆 [英] Output debug via printf on a Cortex-M3 CPU, stalls at BKPT instruction + confusion about JTAG and sw ports

查看:478
本文介绍了通过Cortex-M3 CPU上的printf进行输出调试,停止BKPT指令+关于JTAG和sw端口的混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Keil ULINK2 USB模拟器框连接到我的电路板上的 JTAG 连接器,这可以在机载Cortex-M3 CPU(TI / Stellaris / LuminaryMicro LM3S系列)上正常工作。 JTAG和SWJ-DP端口似乎在这些CPU上共享相同的引脚(以及板上的连接器)。一个似乎没有ITM(printf)功能,另一个似乎。以前的固件人们一直使用stdio到UART(串行端口),但是我需要释放串行端口,以便调试消息不会干扰发送的其他数据/接收到/从串行端口,因此我需要跟踪消息去别的地方。可悲的是,我在这个板上只有一个串口。我以为这个CPU中的ITM(Trace)功能意味着我可以将调试printf消息直接发送到我的调试器/ IDE(Keil uVision)。 TI / Stellaris CPU文档称之为串行线JTAG调试端口(SWJ-DP)的功能,我已经阅读的支持绝对是Keil uVision IDE中实现的功能。



将printf消息添加到我的代码会导致我的代码在我开始调试时锁定。锁定似乎在RTL库中,这些库链接到我的应用程序中,函数_sys_open中的BKPT指令:

  _sys_open:
0x00009D7A B50E PUSH {r1-r3,lr}
0x00009D7C E9CD0100 STRD r0,r1,[sp,#0]
0x00009D80 F7FFFC0F BL.W strlen(0x000095A2)
0x00009D84 9002 STR r0,[sp,#0x08]
0x00009D86 4669 MOV r1,sp
0x00009D88 2001 MOVS r0,#0x01
>> 0x00009D8A BEAB BKPT 0xAB
0x00009D8C BD0E POP {r1-r3,pc}

以上似乎是由 __ rt_lib_init_stdio_1



发生了什么事?我不知道BKPT做什么。我假设它提出一个软件断点,然后由调试器处理? Keil / ARM ULINK2软件和硬件是否应该不配置?使用Keil JTAG / sw端口进行调试printf有一些窍门吗?



我不确定sw和JTAG端口之间的区别是什么。 sw是什么意思,我相信它是指板上JTAG物理连接器的两种可能模式之一,其中JTAG是经典的但是更有限的模式,无需跟踪支持,sw模式增加了跟踪支持,而不需要向JTAG添加任何引脚连接器布局?但这是嵌入式系统,其中隐藏是常态。我是Cortex-M3开发的新手,而且自从旧的ARM7TDMI天以来,很多这样的东西对我而言都是新的。但是Keil uVision打印出这个消息:ITM只能使用SW端口,而不是JTAG。 SW是不同的物理端口,您必须在您的板上设计? (我正在使用自定义设计的应用程序板,而不是开发入门板。)



[Googling around让我了解到 _sys_open 和一些pragma __ use_no_semihosting_swi 和其他一些事情密切相关的这个难题,ROM中的BRKPT指令可能是SWI上的一些ARM变体('软件中断')ARM指令。]

解决方案

这个我没有理解stdio没有实现,而是你必须提供自己的实现,通常在一个名为retarget.c的文件中完成。文件名是纯粹的惯例,但是在Keil的uVision / RTLIB文档中已经有很好的文档(原来是这样)


I have a Keil ULINK2 USB emulator box attached to the JTAG connector on my board, which is working fine with the Cortex-M3 CPU onboard (TI/Stellaris/LuminaryMicro LM3S series). It seems that both a JTAG and a SWJ-DP port share the same pins (and thus connector on your board) on these CPUs. One appears not to have ITM (printf) capability, the other does.

The previous firmware people have always used stdio to UART (serial port), but I need the serial port freed up so that debug messages do not interfere with other data being sent/received to/from the serial port, thus I need for trace messages to go elsewhere. Sadly I only have one serial port on this board. I thought that the ITM (Trace) feature in this CPU meant that I could send debug printf messages directly to my debugger/IDE (Keil uVision). The TI/Stellaris CPU documentation call this feature 'Serial Wire JTAG Debug Port (SWJ-DP)', support for which, I have read, is definitely a feature implemented in the Keil uVision IDE.

Adding a printf message to my code causes my code to lock up when I start debugging. The lockup seems to be here in the RTL libraries which are linked into my application, in the function _sys_open, at the BKPT instruction:

                 _sys_open:
  0x00009D7A B50E      PUSH     {r1-r3,lr}
  0x00009D7C E9CD0100  STRD     r0,r1,[sp,#0]
  0x00009D80 F7FFFC0F  BL.W     strlen (0x000095A2)
  0x00009D84 9002      STR      r0,[sp,#0x08]
  0x00009D86 4669      MOV      r1,sp
  0x00009D88 2001      MOVS     r0,#0x01
>>0x00009D8A BEAB      BKPT     0xAB
  0x00009D8C BD0E      POP      {r1-r3,pc}

The above appears to be part of code called by __rt_lib_init_stdio_1.

What is going on? I don't know what BKPT does. I assume it raises a software breakpoint which should then be handled by the debugger? Shouldn't the Keil/ARM ULINK2 software and hardware already be configured for this? Is there some trick to making debug printf work with Keil JTAG/sw ports?

I am unsure what the difference between an sw and JTAG port is. sw means what exactly, I believe it refers to one of two possible modes for the JTAG physical connector on a board, where JTAG is a classic but more limited mode without trace support, and sw mode adds trace support without adding any pins to the JTAG connector layout? But this is embedded systems, where being cryptic is the norm. I am new to Cortex-M3 development, and a lot of this stuff is new to me since the old ARM7TDMI days. But the Keil uVision prints this message out: "ITM works only with SW port, not with JTAG". Is SW a different physical port that you have to design on your board? (I am using a custom designed application board, not a development starter board.)

[Googling around lets me in on the fact that _sys_open and some pragma __use_no_semihosting_swi and something else are intimately involved in this puzzle, BRKPT instructions in ROM might be some ARM variant on the SWI ('software-interrupt') ARM instruction.]

解决方案

This one was a failure on my part to understand that stdio is not implemented, but rather you must provide your own implementation, usually done inside a file called "retarget.c". The filename is pure convention, but is well documented (as it turns out) inside Keil's uVision/RTLIB documentation

这篇关于通过Cortex-M3 CPU上的printf进行输出调试,停止BKPT指令+关于JTAG和sw端口的混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆