Embedded Development ARM Technology JTAG Interface Interpretation

JTAG, as commonly referred to, can be roughly divided into two categories: one is used for testing the electrical characteristics of chips to detect any issues; the other is used for debugging. Generally, CPUs that support JTAG contain both modules. A CPU with a JTAG Debug interface module can access the internal registers of the CPU and devices connected to the CPU bus, such as FLASH, RAM, and registers of built-in modules in SOCs (like 4510B, 44Box, AT91M series), including registers for UART, Timers, GPIO, etc., as long as the clock is normal. The above just describes the capabilities of the JTAG interface; to utilize these functions, software support is also required, and the specific functionalities are determined by the software in use. For example, downloading programs to RAM. Those familiar with SOCs know that to use external RAM, one must refer to the SOC Data Sheet for register descriptions to set the base address, bus width, access speed, etc. Some SOCs also require remapping to function correctly. When running firmware, these settings are completed by the firmware’s initialization program. However, if using the JTAG interface, the related registers may still be in their power-on values or even erroneous values, causing RAM to malfunction, and thus the download will inevitably fail. To use it normally, one must first find a way to set the RAM. In ADW, this can be set in the Console window using the Let command, and in AXD, it can be set using the Set command. Below is a command sequence to set up the AT91M40800, disable interrupts, set CS0-CS3, and perform remapping, applicable to AXD (ADS Debug):

setmem 0xfffff124,0xFFFFFFFF,32 ---disable all interrupts setmem 0xffe00000,0x0100253d,32 ---set CS0 setmem 0xffe00004,0x02002021,32 ---set CS1 setmem 0xffe00008,0x0300253d,32 ---set CS2 setmem 0xffe0000C,0x0400253d,32 ---set CS3 setmem 0xffe00020,1,32 ---remap

If using ADW (SDT Debug), it should be changed to:

let 0xfffff124=0xFFFFFFFF ---disable all interrupts let 0xffe00000=0x0100253d ---set CS0 let 0xffe00004=0x02002021 ---set CS1 let 0xffe00008=0x0300253d ---set CS2 let 0xffe0000C=0x0400253d ---set CS3 let 0xffe00020=1 ---remap

For convenience, the above commands can be saved as a file config.ini, and executed in the Console window by entering ob config.ini. Other debuggers are generally similar, but the commands and their formats differ. When setting the RAM, the registers and their values must match the settings of the program to be run. Generally, the target files generated by compilation are in ELF format or similar, containing target code run addresses determined during linking. When debugging and downloading the program, it is downloaded to the specified address based on the address information in the ELF file. If the base address of RAM is set to 0x10000000, while the firmware’s start address is specified at 0x02000000 during compilation, the target code will be downloaded to 0x02000000, and it is evident that the download will fail. Before downloading programs via JTAG, all interrupts should be disabled, which is the same reason as disabling interrupts during firmware initialization. When using the JTAG interface, the enabling of each interrupt is unknown, especially in cases where executable code is present in FLASH, some interrupts may be enabled. After downloading code with JTAG, there may be interrupts triggered due to incomplete initialization, causing the program to behave abnormally. Therefore, interrupts need to be disabled first, generally accomplished by setting the SOC’s interrupt control registers. Writing FLASH using JTAG. In theory, JTAG can access all devices on the CPU bus, so it should be able to write FLASH. However, the writing method for FLASH is quite different from that for RAM; it requires special commands, and different FLASH types have different erase and programming commands, and the sizes and numbers of blocks also vary, making this functionality hard to provide. Thus, most debuggers do not offer FLASH writing capabilities or only support a few types of FLASH. Currently, to my knowledge, only the FlashPGM software provides FLASH writing capabilities for ARM, but it is also quite cumbersome to use. Neither AXD nor ADW provides FLASH writing capabilities. My method for writing FLASH is to write a simple program specifically for writing the target board’s FLASH, download it to the target board via the JTAG interface, and then load the target code to be burned into BIN format onto the target board (the address is different from that of the FLASH writing program), and then run the already downloaded FLASH writing program. This method seems to be faster than using FlashPGM for writing FLASH.

About simple JTAG cables. Currently, there are various simple JTAG cables, which are essentially just a level conversion circuit and also provide protection. The logic for JTAG is implemented by software running on the PC, so theoretically, any simple JTAG cable can support various application software, such as debugging. I have used the same JTAG cable to write Xilinx CPLD and debug programs in AXD/ADW. The key lies in software support, as most software does not provide configuration capabilities, hence only supports certain JTAG cables. Regarding the speed of simple JTAG cables. JTAG is a serial interface, and using a simple JTAG cable via the printer port utilizes the characteristic of latch output from the printer port, and software generates JTAG timing through I/O. According to the JTAG standard, writing/reading a byte via JTAG requires a series of operations. Based on my analysis, using a simple JTAG cable through the printer port, outputting a byte to the target board via JTAG requires an average of 43 printer port I/O operations. On my machine (P4 1.7G), it can perform about 660K I/O operations per second, so the download speed is approximately 660K/43, which is about 15K Bytes/S. For other machines, the I/O speed is generally similar, usually between 600K and 800K. Regarding how to improve JTAG download speed. Clearly, using a simple JTAG cable cannot increase speed. There are generally two ways to improve speed: 1. Use an embedded system that provides a JTAG interface, connecting the embedded system and the microcomputer via USB/Ethernet, which requires using an MCU. 2. Use CPLD/FPGA to provide a JTAG interface, where the CPLD/FPGA and the microcomputer communicate via the EPP interface (generally, microcomputers’ printer ports support EPP mode), and the EPP interface completes data transmission between the microcomputer and CPLD/FPGA, while the CPLD/FPGA manages JTAG timing.

I have implemented both methods. The first method can achieve relatively high speeds, with actual measurements exceeding 200K Bytes/S (note: this is Bytes, not Bits); however, it is relatively complex in hardware and manufacturing. The second method is relatively slower, with speeds reaching a maximum of 96K Bytes/S, but the circuit is simple, easy to manufacture, and the speed can meet the requirements. The second solution also has a drawback: since the CPU is not released during I/O operations, the microcomputer’s CPU appears very busy during program downloads. Overall, I believe that for individual enthusiasts, the second method is more feasible.

Our official QQ group 1:281549832 (this group is full, please join group 2 or 3group. Joining this group is not approved)

Our official QQ group 2:386393398

Our official QQ group 3:398374563

Special thanks to the strong support from netizens.

Our open-source team is continuously expanding, and we hope everyone joins us.

Here, I would like to thank everyone for their strong support!

Embedded Development ARM Technology JTAG Interface Interpretation

Everyone, please pay attention!

Leave a Comment