JTag on Teensy

Status
Not open for further replies.
I started with Arduino just over a year ago then quickly moved to the Teensy, and I've come to realize I need the power to hardware debug my projects. Currently I do not have any hardware to do this and have been waiting until I'm more familiar with the ARM chip before digging in.

I have never used hardware debugging and have yet to find the idiot's guide to enlighten me as to the details. For the Teensy2 I have not found anything useful regarding JTag debugging but from the ATMega32u4 datasheet I see PF4,PF5,PF7 are JTag pins. Can JTag be used with the Teensy2 or is there something about a fuse blocking the interface?
With the Teensy3 I see pins D3,D4,D5,E5,F5 are JTag pins. Will JTag or other hardware debugging be possible? Would something like the Bus Pirate be enough or is specific hardware required for the ARM?
Obviously I have not done much research yet, I'm just wanting word whether or not JTag is even possible for any of the Teensys.

Thanks!
 
Okay, so if I were to manage to solder wires to the correct pins, or somehow attach them, is that all that is necessay to use JTag? Are there and fuses set that would block this? Does the proprietary bootloader block JTag use? Just trying to sort out my future options.

Thanks.
 
Yup, disconnecting those pins from the PCB and soldering wires is "all" you'd need to do.... except of course the JTAG adaptor and the many layers of supporting software!

Freescale Kinetis chips have 16 config bytes in flash at 0x00000400 which are similar to the AVR "fuses". The bootloader does not set the security features in those 16 bytes, so once you physically connect to the JTAG pins, you should have full access.

Of course, if you modify a Teensy 3.0 in this way, there's absolutely no support available from PJRC.
 
Wonderful, thank you for confirming this Paul. Once I find the time to dive into learning the Teensy3 I'll have to search for a way to attach to pins that tiny. Its baby steps for me, but I'm glad you confirmed the feasibility of this. I've spent some time reading about JTag today and I think I'm more confused now than when I began.
Many software is available, yes. But I'm having a tough time figure out the hardware portion of this to get something workable.

Thanks Paul.
 
I've been setting up a TI Stellaris boad which has an ARM Cortex-M4 80MHz chip on it rather than the ARM Cortex-M4 40MHz on the Teensy3.
It supports JTAG nicely, ie I can drive it from Eclipse, set breakpoints, examine variables etc. It took a bit of setting up but it does work on open source tools (TI provide proprietary tools I'm not interested in, partly 'cos they only run on Windows). The instruction set on the two processors is the same, I guess, since they are happy to use the same ARM compilers etc. There's other stuff on the Stellaris like an FPU and things I haven't figured out yet, but the board is much bigger than I'd like. It is trying to be an Arduino for ARM and I tend to be trying to squeeze projects into a small (teensy) space.
Anyway if Paul is interested in pursuing this JTAG thing in a later project I'd be interested.
 
Hey Roger, was curious if you could shed some light on some of the memory mapping for the k20 chips since you've gotten jtag up and running on the stellaris board. I've been happily working with my teensy 3.0 but I'm also trying to peak under the hood by getting a standalone k20 chip running. I'm using jtag and openocd and while it seems I can load code onto it, nothing really runs. I have a feeling im not respecting some of the memory mapping and other reserved bytes like Paul mentions a few posts up when he referred to the 16 config bytes in flash at 0x00000400.

If anyone has any advice as to where the actual program memory starts on the k20 chip so I can try to push my code into the right spot, I'm all ears. For now I'll dive back into the huge kinetis pdf and try to decipher more EE jargon.
 
Let's see if I can help. I'm still at the 'blindly follow the examples and hope like hell' stage of this, but I took a look at the ld files for teensy3 and for Stellaris. I'm assuming you have the teensy3 one and you've looked at this part of the ld file for it:
Code:
SECTIONS
{
	.text : {
		. = 0;
		KEEP(*(.vectors))
		*(.startup*)
		/* TODO: does linker detect startup overflow onto flashconfig? */
		. = [B]0x400[/B];
		KEEP(*(.flashconfig*))
		*(.text*)
		*(.rodata*)
		. = ALIGN(4);
		KEEP(*(.init))
		. = ALIGN(4);
		__preinit_array_start = .;
		KEEP (*(.preinit_array))
		__preinit_array_end = .;
		__init_array_start = .;
		KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
		__init_array_end = .;
	} > FLASH = 0xFF
}
The 0x400 I highlighted there must be the 0x400 Paul referred to. I used to understand ld files back in the 80s, I am struggling now though. Anyway over in Stellaris I can see
Code:
SECTIONS
{
	/* This section it's the code, containing the NVIC Vector table that must start at 0x0
	*   Look at the LM4F120H5QR datasheet for details. (Table 2-8. Exception Types)
	*/
    .text : 
    {
    	/*_start_text = .;	/* This is an index to the beginning of .text segment. */
    	KEEP(*(.nvic_table)) /* I should keep the NVIC ISR Table because it's needed by the processor to start. */
        *(.text.*)			/* This contains the code after the ISR table. */
        *(.rodata.*)    	/* Read only data.  */
        _end_text = .;		/* This is an index to the end of .text segment. */
    }>FLASH
So there seems to be no equivalent of the 0x400 reference in the Stellaris. Possibly the .nvic_table reference is the equivalent here, but I can't see where that value is defined, so maybe that isn't much help.
Also, I just tried it again (having saved my setup carefully and even documented how I did it for my own later reference) and it didn't work. It hink it is at least a little temperamental, but I definitely did see it work at least once. I can put the whole demo project somewhere public for you if that's any use.
 
Interesting, now I'm off to learn about ld files and how they work in the toolchain. I suspect that the

KEEP(*(.nvic_table))

line in the stellaris linker and the

KEEP(*(.vectors))

line in the teensy linker may hold the answer to why my bare k20 chip with what seems byte for byte to be the exact blink.hex code is not firing up an led. I suspect in my attempts to get the jtag talking to the chip that I plain overwrote this first set of startup instructions that are necessary to get the chip started up. (at least according to the stellaris file you posted "keep the NVIC ISR Table because it's needed by the processor to start." )

I have to say as a photographer and self taught programmer I was pretty impressed with myself when I get into the more complex underpinnings of arduino, and more so when i started designing and building my own pcbs, but once again I am humbled by obviously being in way over my head. I'll keep doing what I usually do which is reading everything i can find and trying to break examples and then fix them to see how they work, but its definitely a steep learning curve when dealing with all the command line and tool chain jargon.

Thanks for the offer to post the project too, but I don't think I'll need it quite yet, not until I have a bit better understanding of what exactly im doing and if its possible to restore these fuses/launch tables.
 
That link is useful Michael. I'm starting to remember some of this, I used it when I was doing assembly code in the early '80s, similar notation anyway. I found the definition of the nvic_table, that is in a c file I had to copy into the project. It has this near the top:
Code:
// the funny looking void(* myvectors[])(void) basically it's a way to make cc accept an array of function pointers.
__attribute__ ((section(".nvic_table")))
void(* myvectors[])(void) = {
	// This are the fixed priority interrupts and the stack pointer loaded at startup at R13 (SP).
	//												VECTOR N (Check Datasheet)
	// here the compiler it's boring.. have to figure that out
    (void (*)) &_stack_top, 
    						// stack pointer should be 
							// placed here at startup.			0
    rst_handler,			// code entry point					1
    nmi_handler,			// NMI handler.						2
    hardfault_handler,		// hard fault handler.				3
    // Configurable priority interruts handler start here.
    empty_def_handler,		// Memory Management Fault			4
...
It has a lot of interrupt definitions, and note that near the top is the rst_handler, the entry point, which might be what you're looking for. The c file has an equivalent in teensy3: mk20dx128.c where the 'vectors' section is defined and the equivalent lines are:
Code:
__attribute__ ((section(".vectors"), used))
void (* const gVectors[])(void) =
{
        (void (*)(void))((unsigned long)&_estack),	//  0 ARM: Initial Stack Pointer
        ResetHandler,					//  1 ARM: Initial Program Counter
	nmi_isr,					//  2 ARM: Non-maskable Interrupt (NMI)
	hard_fault_isr,					//  3 ARM: Hard Fault
	memmanage_fault_isr,				//  4 ARM: MemManage Fault
Next I looked at the generated .map files for both projects. Where the vectors section is defined (this is on my working teensy3 project) the map looks like this:
Code:
.text           0x00000000     0x4c5c
                0x00000000                . = 0x0
 *(.vectors)
 .vectors       0x00000000       0xf8 /home/roger/workspaceCPP/Teensy_3/Release/libTeensy_3.a(mk20dx128.o)
                0x00000000                gVectors
 *(.startup*)
 .startup       0x000000f8      0x160 /home/roger/workspaceCPP/Teensy_3/Release/libTeensy_3.a(mk20dx128.o)
                0x000000f8                ResetHandler
                0x00000400                . = 0x400
 *fill*         0x00000258      0x1a8 ff
 *(.flashconfig*)
 .flashconfig   0x00000400       0x10 /home/roger/workspaceCPP/Teensy_3/Release/libTeensy_3.a(mk20dx128.o)
                0x00000400                flashconfigbytes
 *(.text*)
 .text          0x00000410       0xb0 /home/roger/sat/lib/gcc/arm-none-eabi/4.7.3/thumb/cortex-m4/crtbegin.o
There's the 0x0400 Paul mentioned and it comes from mk20dx128.c line 161 like this:
Code:
//void usb_isr(void)
//{
//}

__attribute__ ((section(".flashconfig"), used))
const uint8_t flashconfigbytes[16] = {
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
};
These look like fuses to me but I couldn't say more than that without reading a lot more.
Over on the Stellaris the map look like this:
Code:
.text           0x00000000      0x758
 *(.nvic_table)
 .nvic_table    0x00000000      0x26c ./LM4F_startup.o
                0x00000000                myvectors
 *(.text.*)
 .text.rst_handler
                0x0000026c       0x70 ./LM4F_startup.o
                0x0000026c                rst_handler
 .text.nmi_handler
                0x000002dc        0x8 ./LM4F_startup.o
                0x000002dc                nmi_handler
 .text.hardfault_handler
                0x000002e4        0x8 ./LM4F_startup.o
                0x000002e4                hardfault_handler
 .text.empty_def_handler
                0x000002ec        0x8 ./LM4F_startup.o
                0x000002ec                empty_def_handler
 .text.main     0x000002f4       0xa4 ./main.o
                0x000002f4                main
 .text.Timer1A_ISR
                0x00000398       0x2c ./main.o
                0x00000398                Timer1A_ISR
 .text.SysCtlPeripheralEnable
                0x000003c4       0x4c /home/roger/src/stellaris/stellarisware/driverlib/gcc-cm4f/libdriver-cm4f.a(sysctl.o)
                0x000003c4                SysCtlPeripheralEnable
 .text.SysCtlDelay
                0x00000410        0x8 /home/roger/src/stellaris/stellarisware/driverlib/gcc-cm4f/libdriver-cm4f.a(sysctl.o)
                0x00000410                SysCtlDelay
 .text.SysCtlClockSet
                0x00000418      0x164 /home/roger/src/stellaris/stellarisware/driverlib/gcc-cm4f/libdriver-cm4f.a(sysctl.o)
                0x00000418                SysCtlClockSet
So this doesn't have anything special at 0x400. I just checked what Paul said earlier:
Freescale Kinetis chips have 16 config bytes in flash at 0x00000400 which are similar to the AVR "fuses"
I guess the Stellaris is a TI chip not a Freescale one so we would expect it to be different.
However to get the fuses set in (actually they are "fuses") the teensy it ought to be possible to get the mk20dx128.c file and the section definitions from the ld file into your build. Good luck.
 
Be careful if you manipulate those 16 bytes. If you set them incorrectly, it's possible to permanently brick your chip.

While loading code to Teensy 3.0, the bootloader checks your data before writing. If you attempt to permanently disable erasing the chip, it will automatically change that bit before writing.
 
So that Nvic table and the fuse settings get pulled right into the compiler via the ld file (I've never worked with compiler so I'm still puzzling it out). This means that if I grab a post compile hex from the teensyduino and opened it up I would actually see all the vector section in the first 1024 bytes followed immediately by the fuses because they actually get overwritten each time the chip is programmed? I was assuming that on my bare k20 board I had accidentally erased those sections and that they would have been set in factory, but that doesn't make too much sense since the vectors I presume are variable based on your code. So that means that if was just to to write the hex file right onto the chip then I would do so at 0x00. Which seems to be born out when I examine the bytes after writing PWM.cpp.hex as compiled by teensyduino to the chip.

Code:
> flash write_image programs/PWM.cpp.hex 0 ihex
wrote 8192 bytes from file programs/PWM.cpp.hex in 2.260898s (3.538 KiB/s)

>mdb 0 1040         
0x00000000: 00 20 00 20 f9 00 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f5 05 00 00 
0x00000020: f5 05 00 00 f5 05 00 00 f5 05 00 00 f7 05 00 00 f7 05 00 00 f5 05 00 00 f7 05 00 00 f9 05 00 00 
0x00000040: f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 
0x00000060: f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 
0x00000080: 91 0c 00 00 f7 05 00 00 69 0e 00 00 f7 05 00 00 f9 0f 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 
0x000000a0: f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 
0x000000c0: f7 05 00 00 b1 08 00 00 f7 05 00 00 5d 12 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 f7 05 00 00 
0x000000e0: 35 06 00 00 85 06 00 00 0d 07 00 00 c9 07 00 00 4d 08 00 00 f7 05 00 00 45 4b 4c f2 20 52 10 b5 
0x00000100: 1a 80 4d f6 28 12 1a 80 10 22 23 f8 0e 2c 00 f0 7b fa 40 4b 40 4a 1a 60 40 4a 5a 60 40 4b 1a 68 
0x00000120: 12 f4 80 72 04 d1 3f 49 0a 60 4f f4 a8 52 1a 60 00 23 3d 4a 3d 48 3e 4c 02 e0 19 59 99 50 04 33 
0x00000140: 99 18 81 42 f9 d3 3b 4b 3b 4a 00 21 01 e0 43 f8 04 1b 93 42 fb d3 39 4b 00 22 1a 60 38 4b 0a 22 
0x00000160: 1a 70 38 4b 24 22 1a 70 a0 22 03 f8 01 2c 36 4a 13 78 03 f0 02 03 db b2 00 2b f9 d0 32 4a 13 78 
0x00000180: 03 f0 10 03 db b2 00 2b f9 d1 2f 4a 13 78 03 f0 0c 03 08 2b fa d1 2d 4b 03 22 1a 70 40 22 5a 70 
0x000001a0: 29 4a 13 78 03 f0 20 03 db b2 00 2b f9 d0 26 4a 13 78 03 f0 40 03 db b2 00 2b f9 d0 24 4a 25 4b 
0x000001c0: 1a 60 25 4b 20 22 1a 70 1f 4a 13 78 03 f0 0c 03 0c 2b fa d1 21 4b 02 22 1a 60 21 4a 43 f8 44 2c 
0x000001e0: 20 4b 4b f6 7f 32 1a 60 07 22 43 f8 04 2c 62 b6 00 f0 90 fb 0b 4b 1b 68 db 07 02 d5 1a 48 00 f0 
0x00000200: 79 fb 01 f0 75 fd 00 f0 ff f9 01 f0 03 fd fe e7 0e 20 05 40 38 80 04 40 82 3f 04 00 01 00 00 2b 
0x00000220: 10 d0 03 40 14 d0 03 40 60 e5 ff 1f fc e5 ff 1f 64 1f 00 00 fc e5 ff 1f 54 e9 ff 1f 08 ed 00 e0 
0x00000240: 00 50 06 40 01 40 06 40 06 40 06 40 04 40 06 40 00 00 03 11 44 80 04 40 00 40 06 40 48 80 04 40 
0x00000260: c0 10 05 00 14 e0 00 e0 e5 bc 62 51 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000280: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x000002a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x000002c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x000002e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000300: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000320: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000340: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000360: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000380: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x000003a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x000003c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x000003e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x00000400: ff ff ff ff ff ff ff ff ff ff ff ff fe ff ff ff


Prior to flashing the code everything was FF save for the 16 bytes at 0x400 - ff ff ff ff ff ff ff ff ff ff ff ff fe ff ff ff, which seems correct. Now presumably thats the vector table and all the extra blank space is unused vector definitions. Yet when i disconnect the JTAG and restart the chip I don't get any blinky LED love. I'll have to triple check that its not a hardware issue since this is a custom board, but I'd be surprised if the k20 chip was reachable and flashable but won't run code. Ideally I can get some of Paul's compiled code to work to confirm my hardware and then I can dig backward to play with compiling my own code etc. In the end the teensy is obviously the easiest solution for all my limited run and one off projects, but I would like to get this more barebones option working to have in the back pocket.
 
Well with more probing it looks like my code is getting to a Hard Fault so obviously there is still something wrong, gonna attempt to track it down. Here's the output of the chips registers and hard fault should anyone find it interesting. This is all from openOCD by the way.

Code:
> reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
(1) r1 (/32): 0x00000000
(2) r2 (/32): 0x2B000001
(3) r3 (/32): 0x4003D010
(4) r4 (/32): 0x00000000
(5) r5 (/32): 0x00000000
(6) r6 (/32): 0x00000000
(7) r7 (/32): 0x00000000
(8) r8 (/32): 0x00000000
(9) r9 (/32): 0x00000000
(10) r10 (/32): 0x00000000
(11) r11 (/32): 0x00000000
(12) r12 (/32): 0x00000000
(13) sp (/32): 0x20001FD8
(14) lr (/32): 0xFFFFFFF9
(15) pc (/32): 0x000005F6
(16) xPSR (/32): 0x01000003
(17) msp (/32): 0x20001FD8
(18) psp (/32): 0x00000000
(19) primask (/1): 0x00
(20) basepri (/8): 0x00
(21) faultmask (/1): 0x00
(22) control (/2): 0x00
===== cortex-m3 dwt registers
(23) dwt_ctrl (/32)
(24) dwt_cyccnt (/32)
(25) dwt_0_comp (/32)
(26) dwt_0_mask (/4)
(27) dwt_0_function (/32)
(28) dwt_1_comp (/32)
(29) dwt_1_mask (/4)
(30) dwt_1_function (/32)
(31) dwt_2_comp (/32)
(32) dwt_2_mask (/4)
(33) dwt_2_function (/32)
(34) dwt_3_comp (/32)
(35) dwt_3_mask (/4)
(36) dwt_3_function (/32)
> step
target state: halted
target halted due to single-step, current mode: Handler HardFault
xPSR: 0x01000003 pc: 0x000005f6 msp: 0x20001fd8
 
I wonder if there is an alternative dev board using the same CPU as Teensy3.1 that has JTAG/SWD. Or we'll just sacrifice a board to add serial wire debug, usually just 2-3 signals, power and GND.

Personally I think people come to rely on JTAG and single step much too often, rather than being careful about coding. But every once in a while that single step comes in handy. For instance we are looking at adding BREAK/STOP to our BASIC, and the only way we see it is possible is to patch into the USB interrupt handler for DTR. At that point rather than doing an interrupt return we want to restore stack frame and return to the END of a BASIC program. Pretty hard to do it all by wiggling pins, and walking that through the code, though I've done that enough in my day.
 
I used IAR/JTAG (J-Link) for years on ARM7. But as the project neared completion, JTAG connectivity became impractical due to the number of I/O pins lost. More pins that just JTAG signals.
I do like flash breakpoints for stopping when that rare event occurs that's hard to make happen, and you just must trap and analyze.
I agree that single stepping doesn't work - especially in an interrupt driven embedded system. It's not like a novice stepping through C# code on a PC, for sure.

I haven't used newer debugWire and such but would like to.
 
IpsissimusMarr, here's some inspiration for your extreme PCB modding. :p And if you do this, whether it works or not, you really have to post pictures. I'm sure I'm not the only one who'd love to see it.
 
better to scrape a little bit of the conformal coating in the right places, and use fine wire (40ga) to a board that allows you to tack from there. This way you are not digging into the chip, or desoldering anything. You really don't have to desolder or disconnect the other chip either. I also won't disclose how to do this.
 
Well, luckily I have not yet had a need to do this. Although your linked pictures are less than encouraging. When I was originally looking into this what I really wanted was a socket to put over the chip, and link the appropriate pins to JTAG. It was not until this week I found exactly what I had in mind, just for the Atmega32 (Atmel Atmega Socket Firmware Tool).

Anyone know if such a device exists for LQFP64?
 
Status
Not open for further replies.
Back
Top