CHAPTER 15 Debug Architecture
In This Chapter:
The Cortex-M3 processor provides a comprehensive debugging environment. Based on the nature of operations, the debugging features can be classified into two groups:
A number of debugging components are included in the Cortex-M3 processor. The debugging system is based on the CoreSight debug architecture, allowing a standardized solution to access debugging controls, gather trace information, and detect debugging system configuration.
The CoreSight debug architecture covers a wide area, including the debugging interface protocol, debugging bus protocol, control of debugging components, security features, trace data interface, and more. The CoreSight Technology System Design Guide (Ref 3) is a useful document for getting an overview of the architecture. In addition, a number of sections in the Cortex-M3 Technical Reference Manual (Ref 1) are descriptions of the debugging components in Cortex-M3 design. These components are normally used only by debugger software, not by application code. However, it is still useful to briefly review these items so that we can have a better understanding of how the debugging system works.
Unlike traditional ARM7 or ARM9, the debugging system of the Cortex-M3 processor is based on the CoreSight Debug Architecture. Traditionally, ARM processors provide a JTAG interface, allowing registers to be accessed and memory interface to be controlled. In the Cortex-M3, the control to the debug logic on the processor is carried out via a bus interface called the Debug Access Port (DAP), which is similar to APB in AMBA. The DAP is controlled by another component that converts JTAG or Serial-Wire into the DAP bus interface protocol.
Since the internal debug bus is similar to APB, it is easy to connect multiple debugging components, resulting in a very scalable debugging system. In addition, by separating the debug interface and debug control hardware, the actual interface type used on the chip can become transparent; hence the same debugging tasks can be carried out no matter what debugging interface you use.
The actual debugging functions in the Cortex-M3 processor core are controlled by the NVIC and a number of other debugging components, such as the FPB, the DWT, and the ITM. The NVIC contains a number of registers to control the core debugging actions, such as halt and stepping, while the other blocks support features such as watchpoints, breakpoints, and debug message outputs.
CoreSight technology supports a number of interface types for connection between the debug host and the SoC. Traditionally this has always been JTAG. Now, since the processor debugging interface has been changed to a generic bus interface, by putting a different interface module between the debug host and the processor’s debug interface we can come up with different chips that have different debug host interfaces, without redesigning the debug interface on the processor.
Currently Cortex-M3 systems support two types of debug host interface: The first one is the well-known JTAG interface, and the second one is a new interface protocol called Serial-Wire (SW). The SW interface reduces the number of signals to two. Several types of debug host interface modules (called Debug Port, or DP) are available from ARM. The debugger hardware is connected to one side of a DP, and the other side is connected to the DAP interface on the processor.
Why Serial-Wire?
The Cortex-M3 is targeted at the low-cost microcontroller market in which most devices have very low pin counts. For example, some of the low-end versions are in 28-pin packages. Despite the fact that JTAG is a very popular protocol, using four pins to debug is a lot for a 28-pin device. Therefore, SW is an attractive solution because it can reduce the number of debug pins to two.
The connection from external debugging hardware to the debug interface in the Cortex-M3 processor is divided into multiple stages (see Figure 15.1).
The DP interface module (normally either SWJ-DP or SW-DP) first converts the external signals into a generic 32-bit debug bus (a DAP bus in the diagram). SWJ-DP supports both JTAG and SW, and SW-DP supports SW only. In the ARM CoreSight product series there is also a JTAG-DP, which only supports the JTAG protocol; chip manufacturers can choose to use one of these DP modules to suit their needs. The address of the DAP bus is 32-bit, with the upper 8 bits of the address bus used to select which device is being accessed. Up to 256 devices can be attached to the DAP bus. Inside the Cortex-M3 processor, only one of the device addresses is used, so you can attach 255 more Access Port (AP) devices to the DAP bus if needed.
After passing through the DAP interface in the Cortex-M3 processor, an AP device called AHB-AP is connected. This acts as a bus bridge to convert commands into AHB transfers, which are inserted into the internal bus network inside the Cortex-M3. This allows the memory map of the Cortex-M3, including the debug control registers in the NVIC, to be accessed.
In the CoreSight product series, several types of AP devices are available, including an APB-AP and a JTAG-AP. The APB-AP can be used to generate APB transfers, and the JTAG-AP can be used to control traditional JTAG-based test interfaces such as the debug interface on ARM7.
Another part of the CoreSight architecture concerns tracing. In the Cortex-M3, there can be three types of trace sources:
During tracing, the trace results, in the form of data packets, are output from the trace sources like ETM, using a trace data bus interface called Advanced Trace Bus (ATB). Based on the CoreSight architecture, if a SoC contains multiple trace sources (e.g., multiprocessors), the ATB data stream can be merged using ATB merger hardware (in the CoreSight architecture this hardware is called ATB funnel). The final data stream on the chip can then be connected to a Trace Port Interface Unit (TPIU) and exported to external trace hardware. Once the data reach the debug host (for example, a PC), the data stream can then be converted back into multiple data streams.
Despite the Cortex-M3 having multiple trace sources, its debugging components are designed to handle trace merging so that there is no need to add ATB funnel modules. The trace output interface can be connected directly to a special version of the TPIU designed for the Cortex-M3. The trace data are then captured by external hardware and collected by the debug host (e.g., a PC) for analysis.
The CoreSight-based design has a number advantages:
The debugging system used in the Cortex-M3 processor is slightly different from the standard CoreSight implementation:
In the Cortex-M3, the debugging devices share the same system memory map (see Figure 15.3).
Additional information about the CoreSight Debug Architecture can be found in the CoreSight Technology System Design Guide (Ref 3).
There are two types of debug operation modes in the Cortex-M3. The first one is halt, whereby the processor stops program execution completely. The second one is the debug monitor exception, whereby the processor executes an exception handler to carry out the debugging tasks while still allowing higher-priority exceptions to take place. Debug monitor is exception type 12 and its priority is programmable. It can be invoked by means of debug events as well as by manually setting the pending bit. In summary:
The reason for having a debug monitor is that in some electronic systems, stopping a processor for a debugging operation can be infeasible. For example, in automotive engine control or hard disk controller applications, the processor should continue to serve interrupt requests during debugging, to ensure safety of operations or to prevent damage to the device being tested. With a debug monitor, the debugger can stop and debug the Thread level application and lower-priority interrupt handlers while higher-priority interrupts and exceptions can still be executed.
To enter halt mode, the C_DEBUGEN bit in the NVIC Debug Halting Control and Status Register (DHCSR) must be set. This bit can only be programmed via the DAP, so you cannot halt the Cortex-M3 processor without a debugger. After C_DEBUGEN is set, the core can be halted by setting the C_HALT bit in DHCSR. This bit can be set by either the debugger or by the software running on the processor itself.
The bit field definition of DHCSR differs between read operations and write operations. For write operations, a debug key value must be used on bit 31 to bit 16. For read operations, there is no debug key and the return value of the upper half word contains the status bits (see Table 15.1).
In normal situations, the DHCSR is used only by the debugger. Application codes should not change DHCSR contents to avoid causing problems to debugger tools.
The Cortex-M3 can enter debug mode (both halt or debug monitor exception) for a number of possible reasons. For halt mode debugging, the processor will enter halt mode if conditions resemble those shown in Figure 15.4.
The external debug request is from a signal called EDBGREQ on the Cortex-M3 processor. The actual connection of this signal depends on the microcontroller or SoC design. In some cases this signal could be tied low and never occur. However, this can be connected to accept debug events from additional debug components (chip manufacturers can add extra debug components to the SoC) or, if the design is a multiprocessor system, it could be linked to debug events from another processor.
After debugging is completed, the program execution can be returned to normal by clearing the C_HALT bit.
Similarly, for debugging with the debug monitor exceptions, a number of debug events can cause a debug monitor to take place (see Figure 15.5).
For debug monitor, the behavior is a bit different from halt mode debugging. This is because the debug monitor exception is just one type of exception and can be affected by the current priority of the processor if it is running another exception handler.
After debugging is completed, the program execution can be returned to normal by carrying out an exception return.
One of the most commonly used debug features in most microcontrollers is the breakpoint feature. In the Cortex-M3, two types of breakpoint mechanisms are supported:
The breakpoint instruction (BKPT immed8) is a 16-bit Thumb instruction with encoding 0xBExx. The lower 8 bits depend on the immediate data given following the instruction. When this instruction is executed, it generates a debug event and can be used to halt the processor core if C_DBGEN is set or, if debug monitor is enabled, it can be used to trigger the debug monitor exception. Since the debug monitor is one type of exception with programmable priority, it can only be used in Thread or exception handlers with priority lower than itself. As a result, if debug monitor is used for debugging, the BKPT instructions should not be used in exception handlers such as NMI or hardfault, and the debug monitor can only be pended and executed after the exception handler is completed.
When the debug monitor exception returns, it is returned to the address of the BKPT instruction, not the address after the BKPT instruction. This is because in normal use of breakpoint instructions, the BKPT is used to replace a normal instruction, and when the breakpoint is hit and the debug action is carried out, the instruction memory is restored to the original instruction and the rest of the instruction memory is unaffected.
If the BKPT instruction is executed with C_DEBUGEN = 0 and MON_EN = 0, it will cause the processor to enter a hard fault exception, with DEBUGEVT in the Hard Fault Status Register (HFSR) set to 1, and BKPT in the Debug Fault Status Register (DFSR) also set to 1.
The FPB unit can be programmed to generate breakpoint events even if the program memory cannot be altered. However, it is limited to six instruction addresses and two literal addresses. More information about FPB is covered in the next chapter.
Two more registers are included in the NVIC to provide debug functionality. They are the Debug Core Register Selector Register (DCRSR) and the Debug Core Register Data Register (DCRDR) (see Tables 15.3 and 15.4). These two registers allow the debugger to access processors’ registers. The register transfer feature can be used only when the processor is halted.
To use these registers to read register contents, the following procedure must be followed:
Similar operations are needed for writing to a register:
The DCRSR and the DCRDR registers can only transfer register values during halt mode debug. For debugging using a debug monitor handler, the contents of some of the register can be accessed from the stack memory; the others can be accessed directly within the monitor exception handler.
The DCRDR can also be used for semihosting if suitable function libraries and debugger support are available. For example, when an application executes a printf statement, the text output could be generated by a number of putc (put character) function calls. The putc function calls can be implemented as functions that store the output character and status to the DCRDR and then trigger debug mode. The debugger can then detect the core halt and collect the output character for display. This operation, however, requires the core to halt, whereas the semihosting solution using ITM does not have this limitation.
The NVIC also contains a number of other features for debugging. These include the following:
1TrustZone is an ARM technology that provides security features to embedded products.
18.218.196.182