circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

Issue 143 June 2002
Still Swimming With the STK500
Onto the JTAG ICE


by Fred Eady

Last month, Fred introduced us to Atmel’s STK500, which is the starter kit for the company’s AVR flash memory microcontrollers. This month, he tackles coding and debugging with Atmel’s JTAG ICE. He’s thrilled with the result, so don’t miss this follow-up.


Start Using the JTAG ICE ATMEGA16 in Charge Sources & PDF

Between visits from the usual musically inclined guests and deploying the Atmel armed forces camped in the Florida Room, it’s been a busy month. Amidst the hustle, I realized that thus far I’ve had no problems getting help from the Atmel staff and the JTAG ICE and STK500 development board work perfectly together as an AVR microcontroller development system. In addition to the great Atmel hardware, I’m using some awesome supporting software products as well. I’ve installed a new and more helpful version of Atmel AVRStudio, and the ANSI-based ImageCraft AVR C compiler has proven to be just as good as AVR assembler when it comes to generating efficient AVR assembler code. The future’s so bright I need to wear RayBans. Some of the folks back home in Tennessee would say that I’m as happy as a hog loose in the corn crib.

I’ve been working toward putting one or both of the AVR devices I have in the Florida room on the Internet. In addition to the ATmega163 and ATmega16 parts, I’ve acquired some ATmega128 micros as well. I don’t have the STK501 plug-in that allows the STK500 development board to support the ATmega128 right now, but I will try to get my hands on one so I can do something down the road with the heavy-duty ATmega128 micro. At this point in time, I’m sure the ATmega16 and ATmega163 can handle the application at hand. So, with that let’s slip and slide our way towards the Internet on the JTAG ICE.

 

AVR JTAG ICE

The JTAG ICE functionality is enhanced with the new version 4 of AVRStudio. With an ATmega16 mounted on the STK500 development board and the JTAG ICE connected, I have a full view of the ATmega16 internals. I can also debug my code using ImageCraft’s ICCAVR C source or the AVR assembler generated by the ImageCraft AVR C compiler.

The JTAG ICE works its magic using a concept called on-chip debugging (OCD). Most of the microcontroller emulators that you and I have encountered use a specialized bond-out integrated circuit that contains the CPU and I/O cores of the microcontroller it’s emulating. Thus, the code is actually running on the bond-out device, and the supporting emulator hardware and software have the ability to reach into the bond-out and pull out the microcontroller internals for inspection and debugging. Instead of depending on a bond-out device, the JTAG ICE interfaces with the target AVR’s internal OCD system via the JTAG IEEE 1149.1-compliant interface.

Every AVR microcontroller with a JTAG pin set houses OCD logic. The JTAG ICE takes control of the target AVR and controls the execution of the firmware using the OCD logic via the target’s JTAG interface pin set. Because the code is actually running on the real device, the target device’s original electrical and timing characteristics are retained. The JTAG ICE/OCD combination has several advantages over traditional emulator methods, but there are some things this duo cannot perform. For instance, the trace buffer function is not a part of the OCD.

If you’ve ever had to interface to anyone’s emulator, you know that there are some basic operations common to them all. The JTAG ICE is no different. When the AVR JTAG ICE is in Run mode, code execution is not a JTAG ICE concern. JTAG ICE polls the running target looking for a break condition. When a break is sensed, the OCD goes to work and uses the JTAG interface to reach into the target AVR and pull out the same information a standard emulator would. Remember, the OCD doesn’t incorporate a trace buffer function. So, all you get is information captured at the time of the break event, minus execution history up to that point.

When a break point is encountered, program execution, as far as JTAG ICE is concerned, is halted. But, because the JTAG ICE doesn’t contain the CPU and I/O core of the device it’s attached to, the AVR I/O operations that were executing at the break point continue to run. The best example of this is the ability of a standard emulator to trace a UART transmit function bit by bit. JTAG ICE will only see the result of the operation because the I/O in the target will complete the operation regardless of the break point.

Speaking of break points, the AVR OCD can handle hardware and software break points. AVR software break points are placed in the normal code path. The instruction that resides at the selected software break point location is replaced by the break instruction. When the software break point is reached, the code execution halts. To continue, a start command must be issued to the OCD. At that point, the actual instruction at the break point is executed and the code moves on to completion or the next break point.

The AVR family is flash memory-based as far as program memory is concerned. So, using software break points is not as healthy as using hardware break points, in that every time you change the break point in your code you must reprogram the AVR as well. The AVRs are good for at least 1000 program flash-memory write/erase cycles. Theoretically, you can debug a guaranteed 1000 times using software break points exclusively. In my experience with flash memory-based microcontrollers, this 1000-cycle limit is conservative and I can recall only one time that I may have exhausted a part by reprogramming it beyond the prescribed write/erase limits.

If you feel you will exceed 1000 limit write/erase cycles during the development of your project, go for the hardware break point system offered by the JTAG ICE. The AVR OCD logic has four registers available that can each store one memory address. One of the four registers is reserved by the JTAG ICE for performing the single step function. That leaves three of the registers free for you to use as hardware break point containers.

Before you start to get comfortable with the JTAG ICE, three break point registers doesn’t sound like enough. The unique implementation of the three free hardware break point registers makes up for the seeming lack of break point quantity. You can use each break point as a general-purpose break point, which gives you three traditional set and clear break point types, or you can use up to two of the three break points as data break points with the leftover break points remaining for general-purpose use. If you want to get fancy, you can dedicate two break point locations to a mask that operates against the AVR’s SRAM or flash memory.

A general-purpose break point can be placed anywhere, including anywhere in an assembler program or anywhere a valid statement resides in a C program. The break will occur before the execution of the code at the break location. Data memory break points are a tad more complex. You must select one of three break point modes, which consist of a combination of reading and writing the data memory area (SRAM). Data memory break points are invalid for the Register file.

Because nothing is free, when it comes to embedded computing you pay for the data memory break points by having to use a symbolic variable-capable compiler or assembler. I’m using ICCAVR so I’m covered if data memory break points are in the future. Another difference to note is that the break occurs after executing the instruction when using the data memory break point feature.

Masked break points use an address base and address mask, which are ANDed together to generate the break points. The address base is a symbol name or a memory address. The result of the AND is then compared against the program counter or data address to check for a valid break condition. Setting a bit in the mask to zero makes that a “don’t care” bit position. “Don’t care” bits always generate a valid break point regardless of the logic level of the corresponding program counter or data address bit.

If the mask bit is a one, this forces the program counter or data address bit to be the same logic level as the corresponding bit in the base address. Think of the mask break point mask in this way: If you set all of the bits in the address mask high, only the base address would generate a break point. Conversely, if you set all of the mask bits low, all of the addresses would cause a break point. Like the data memory break points, the masked break points break execution after executing the instruction at the break point address. A real example of a masked break point is depicted in the double-wide screen shot in Photo 1.

(Click here to enlarge)

Photo 1—UCSRC is at address 0x20. Note that the write to UCSRC was performed before the break point halted the code.

There’s one more break point that has absolutely nothing to do with the general-purpose break points: break on branch/skip. This break point works on a change of program flow. That means that anything that interrupts the normal flow of a program such as jumps, branches, calls, skips, or interrupt handling will generate a break point after executing the instruction that caused the break point.

I have used the three general-purpose hardware break points and single stepping for most of the debugging so far. Despite the absence of certain standard emulator features, the JTAG ICE and AVRStudio version 4 do a good job of telling you what’s going on inside that target ATmega micro.

While I’m on the subject of what’s inside, I could not resist taking my JTAG ICE apart to see what makes it tick. From left to right in Photo 2, the first IC is a MAX232 RS-232 interface. The 44-pin TQFP next to it is an ATmega163 running at 7.37 MHz. It really makes me feel good to know that Atmel uses its own stuff to build its development tools. The large IC surrounded by who knows what is a 74HC244D octal buffer that is being protected by a couple of ProTek Devices SM16LC08 high-speed TVS diode arrays. The rest of the high-rise components and their strip malls handle the JTAG ICE power details. The bottom line is that the real tricks are done with AVR firmware and the AVRStudio front-end code.

(Click here to enlarge)

Photo 2—There…I’ve gone and blown the warranty. By the way, there’s nothing on the other side of the board.