How JTAG Works for Debugging and Flash Programming
This article explains how the IEEE 1149.1 JTAG interface enables single-step hardware debugging and flash programming in embedded electronics. It covers the fundamental architecture of the Test Access Port (TAP), the boundary scan mechanism, direct processor core control for step-by-step code execution, and the methods used to write firmware directly to non-volatile memory.
The IEEE 1149.1 Standard and TAP Architecture
Originally developed to test circuit boards after manufacturing, the IEEE 1149.1 standard—commonly known as JTAG (Joint Test Action Group)—provides a serial communication interface directly into the silicon of an integrated circuit. At the heart of this interface is the Test Access Port (TAP) controller, a 16-state finite state machine driven by four mandatory signals (and one optional reset signal):
- TCK (Test Clock): Synchronizes the internal state machine operations.
- TMS (Test Mode Select): Determines the next state of the TAP controller on the rising edge of TCK.
- TDI (Test Data In): Serial input for shifting instructions and data into the device.
- TDO (Test Data Out): Serial output for shifting data out of the device.
- TRST (Test Reset): An optional pin that resets the TAP controller to its initial state.
By manipulating the TMS and TCK lines, an external hardware debugger can navigate the TAP state machine to load specific commands into the Instruction Register (IR) and subsequently shift data into or out of various Data Registers (DR).
Enabling Single-Step Hardware Debugging
Modern microcontrollers and processors extend the standard JTAG architecture by connecting internal debug modules (such as ARM CoreSight or RISC-V Debug Modules) as specific Data Registers within the JTAG chain. This direct silicon access allows engineers to control the CPU without relying on running software.
Halting the Processor
To initiate debugging, the external JTAG probe shifts a specific debug instruction into the Instruction Register. It then writes a "halt" command into the internal debug control register via the Data Register path. This signal intercepts the CPU's clock or instruction fetch pipeline, freezing execution immediately.
Reading and Modifying State
Once halted, the debugger uses JTAG to access the processor's internal buses and registers. By shifting data through the JTAG port, the debugger can read the Program Counter (PC), inspect general-purpose registers, and view the contents of RAM. The engineer can also overwrite these values by shifting new data in via the TDI line.
Single-Stepping Execution
Single-stepping is achieved through hardware-level breakpoint and clock control mechanisms:
- The debugger writes to the debug control register to set a "single-step" flag.
- The debugger commands the CPU to resume execution.
- The hardware debug module allows the CPU to fetch and execute exactly one assembly instruction.
- Immediately upon completion of that instruction, the internal hardware automatically re-asserts the halt signal.
- The JTAG probe polls the status register, detects the halt, and shifts out the updated CPU register values to display the results to the developer.
Enabling Flash Programming
Flash memory requires specific sequences of voltages, commands, and timing to erase and write data. JTAG enables flash programming on blank or bricked circuit boards using two primary methods.
Method 1: Boundary Scan Bit-Banging
Every pin on a JTAG-compliant chip is backed by a "boundary scan cell." These cells form a continuous shift register (the Boundary Scan Register) around the perimeter of the silicon die.
When the EXTEST instruction is loaded into the JTAG
Instruction Register, the chip's core logic is disconnected from its
physical pins, and the JTAG interface takes direct control of the pins.
If an external flash chip is connected to the processor, the JTAG probe
can shift bit patterns into the Boundary Scan Register to manually
toggle the address, data, and control pins connected to the flash
memory. While universally compatible, this "bit-banging" approach is
slow because every single pin transition requires shifting hundreds of
bits through the JTAG chain.
Method 2: Debug Module and RAM Loader (Fast Programming)
For internal flash memory or high-speed programming of external flash, debuggers bypass boundary scan and use the CPU's internal bus access:
- Halt and Initialize: The JTAG probe halts the CPU and configures the memory controller registers so that system RAM and flash memory are accessible.
- Upload Flash Algorithm: The debugger shifts a small, compiled program (the "flash loader") directly into the microcontroller's internal RAM.
- Transfer Firmware Data: The debugger shifts a block of the target firmware into a designated buffer area in RAM.
- Execute: The debugger sets the CPU's Program Counter to the start of the flash loader in RAM and releases the CPU from its halted state.
- Write to Flash: The CPU runs at full clock speed, executing the flash loader to copy the firmware buffer from RAM into the flash memory while handling all necessary unlock sequences and timing delays.
- Repeat: Once the block is written, the flash loader triggers a hardware breakpoint. The JTAG probe detects the halt, loads the next chunk of firmware into RAM, and repeats the process until the entire memory is programmed.