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.]