| |||
| Home > Debug > Using the debug functionality > Debug communications channel | |||
There are two ways that an external debugger can send data to or receive data from the core:
The debug communications channel, when the core is not in debug state. It is defined as a set of resources used for communicating between the external debugger and a piece of software running on the core.
The mechanism for forcing the core to execute ARM instructions, when the core is in debug state. See Executing instructions in debug state for details.
At the core side, the debug communications channel resources are:
CP14 Debug Register c5 (DTR)
CP14 Debug Register c1 (DSCR).
Implementations of the ARMv7 debug for the processor are so that:
If a read of the CP14 DSCR returns 1 for the DTRRXfull flag, then a following read of the CP14 DTR returns valid data and DTRRXfull is cleared. No prefetch flush is required between these two CP14 instructions.
If a read of the CP14 DSCR returns 0 for the DTRRXfull flag, then a following read of the CP14 DTR returns an Unpredictable value.
If a read of the CP14 DSCR returns 0 for the DTRTXfull flag, then a following write to the CP14 DTR writes the intended 32-bit word, and sets DTRTXfull to 1. No prefetch flush is required between these two CP14 instructions.
If a read of the CP14 DSCR returns 1 for the DTRTXfull flag, then a following write to the CP14 DTR is Unpredictable.
When nonblocking mode is selected for DTR accesses, the following conditions are true for memory-mapped DSCR, memory-mapped DTRRX, and DTRTX registers:
If a read of the memory-mapped DSCR returns 0 for the DTRRXfull flag, then a following write of the memory-mapped DTRRX passes valid data to the processor and sets DTRRXfull to 1.
If a read of the memory-mapped DSCR returns 1 for the DTRRXfull flag, then a following write of the memory-mapped DTRRX is ignored, that is, both DTRRXfull and DTRRX contents are unchanged.
If a read of the memory-mapped DSCR returns 1 for the DTRTXfull flag, then a following read of the memory-mapped DTRTX returns valid data and clears DTRTXfull.
If a read of the memory-mapped DSCR returns 0 for the DTRTXfull flag, then a following read of the memory-mapped DTRTX is ignored, for example, the content of DTRTXfull is unchanged and the read returns an Unpredictable value.
Other uses of the DCC resources are not supported by the ARMv7 debug architecture. In particular, ARMv7 debug does not support the following:
polling CP14 DSCR[30:29] flags to access the memory-mapped DTRRX and DTRTX registers
polling memory-mapped DSCR[30:29] flags to access CP14 DTR.
Using the DCC in any of the nonsupported ways can be subject to race conditions.
Software running on the processor that sends data to the debugger through the transmit channel can use the following sequence of instructions as shown in Example 12.2.
Example 12.2. Transmit data transfer (target end)
; r0 -> word to send to the debugger
WriteDCC MRC p14, 0, PC, c0, c1, 0
BCS WriteDCC
MCR p14, 0, Rd, c0, c5, 0
BX lr
Example 12.3 shows the sequence of instructions for sending data to the debugger through the receive channel.
A debugger accessing the DCC through the external interface when not in debug state can use the pseudo-code operations as shown in this section.
Example 12.4 shows the code for transmit data transfer.
Example 12.4. Transmit data transfer (host end)
uint32 ReadDCC()
{
// Step 1. Poll DSCR until DTRRXfull is set.
repeat
{
scr := ReadDebugRegister(34);
}
until (dscr & (1<<29));
// Step 2. Read the value from DTRRX.
dtr_val := ReadDebugRegister(35);
return dtr_val;
}
Example 12.5 shows the code for receive data transfer.
Example 12.5. Receive data transfer (host end)
WriteDCC(uint32 dtr_val)
{
// Step 1. Poll DSCR until DTRTXfull is clear.
repeat
{
dscr := ReadDebugRegister(34);
}
until (!(dscr & (1<<30)));
// Step 2. Write the value to DTRTX.
WriteDebugRegister(32, dtr_val);
}
While the processor is running, if the DCC is being used as a data channel, it might be appropriate to poll the DCC regularly.
Example 12.6 shows the code for polling the DCC.
Example 12.6. Polling the DCC (host end)
PollDCC
{
dscr := ReadDebugRegister(34);
if (dscr & (1<<29))
{
// DTRTX (data transfer register - transmit) full
dtr := ReadDebugRegister(35)
ProcessTransmitWord(dtr);
}
elseif (!(dscr & (1<<30)))
{
// DTRRX (data transfer register - receive) empty
dtr := GetNextReceiveWord();
}
}