ITM driver header.
This driver implements APIs to configure and control the ARM Instrumentation Trace Macrocell (ITM), Debug Watchpoint and Trace (DWT), and Trace Port Instrumentation Unit (TPIU) IPs to realize non-intrusive software logging and runtime trace.
The ITM software module provides application level APIs for the non-invasive debug capabilities of the ARM Cortex-M family. This includes the following hardware modules:
At a high level, the DWT provides watchpoint, data trace, and program counter sampling. The ITM provides memory mapped registers for low-intrusion software profiling. The TPIU provides an external interface for the ITM and DWT. Further details can be found in the ARMv7-M Architecture Reference Manual
The driver is is designed with the following constraints in mind:
The ITM is configured via hardware attributes stored in the hardware attributes structure. This structure contains a common portion that is used for all drivers. This structure may be extended for some devices such as CC26XX.
Unlike other drivers, the ITM is intended to be a singleton. This means that ITM_open can be called multiple times. The ITM will only be configured the first time open is called.
Furthermore, helper functions for features such as PC sampling must coherent across clients. The driver offers no protection against mismatched configuration.
The open call will enable ITM as well as the necessary stimulus ports. It will setup the TPIU for necessary baudrate and serial format.
As the ITM driver is primarily interfacing to ARM defined IP, it is almost entirely common across all supported devices. The only specifics are pin muxing of the SWO pin. See the table below for some notes
Device Family | Debug Protocol | Muxing | Configurable? |
---|---|---|---|
CC32XX | SWD | Shared with TDO | N |
CC13XX/CC26XX | JTAG/cJTAG | Any pin | Y |
Device specific pin muxing is done by the device specific ITM backend implementation.
The ITM stimulus ports enable serialization of application data with low overhead. There are multiple ports available, they are selectable via software.
Data written to the software stimulus ports is serialized by the TPIU and wrapped in the SWIT packet format. This packet format is standardized by ARM and described in ARMv7-M Architecture Reference Manual
There are three tiers of access to the stimulus ports. In the table below, polled access means that the API/macro will poll the port's busy flag before writing. This is done to prevent silent data loss that occurs when writing to a port that is not ready. Actual serialization of the data will occur later inside the TPIU.
It is up the the application writer to understand the tradeoff associated with each of these and select the correct one.
The Data Watchpoint and Trace (DWT) module is capable of many instrumentation features such as
Feature | ITM API |
---|---|
Exception trace | ITM_enableExceptionTrace |
Program Counter sampling | ITM_enablePCSampling |
Event counting | ITM_enableEventCounter |
Synchronization packets | ITM_enableSyncPackets |
Data generated by the DWT is serialized via the TPIU. DWT packet formats are defined in the ARMv7-M Architecture Reference Manual referenced above
The ITM/DWT/TPIU hardware resides in the CPU power domain. This means that whenever the CPU domain is powered down, ITM will power down. Powering down when data is inside in the TPIU can result in lost data. In order to prevent dataloss, the device's power policy will flush the ITM before powering down the CPU domain. When returning from sleep, the power policy will restore the ITM. This is achieved using the ITM_flush and ITM_restore.
These functions are weakly defined as empty functions. This reduces the overhead in the power policy when ITM is not enabled. These weak functions are overridden by syscfg when ITM is enabled.
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <ti/devices/DeviceFamily.h>
Go to the source code of this file.
Data Structures | |
struct | ITM_HWAttrs |
ITM Hardware Attributes. More... | |
Macros | |
#define | ITM_BASE_ADDR (0xE0000000) |
Base address of the Instrumentation Trace Macrocell (ITM) module. More... | |
#define | ITM_DWT_BASE_ADDR (0xE0001000) |
Base address of the Debug Watchpoint and Trace (DWT) module. More... | |
#define | ITM_SCS_BASE_ADDR (0xE000E000) |
Base address of the CPU_SCS module. More... | |
#define | ITM_TPIU_BASE_ADDR (0xE0040000) |
Base address of the Trace Port Instrumentation Unit (TPIU) module. More... | |
#define | ITM_LAR_UNLOCK (0xC5ACCE55) |
Value to unlock ARM debug modules. This value should be written to the Lock Access Registers (LAR) in order to enable their configuration and use. More... | |
#define | ITM_FUNCTION_DISABLED (0x00) |
Device-specific values that implement the generic ITM-functions in ITM_WatchpointAction. More... | |
#define | ITM_FUNCTION_EMIT_PC (0x30 | 0x4) |
#define | ITM_FUNCTION_EMIT_DATA_ON_READ_WRITE (0x800 | 0x20 | 0xc) |
#define | ITM_FUNCTION_EMIT_PC_ON_READ_WRITE (0x800 | 0x30 | 0x2) |
#define | ITM_FUNCTION_EMIT_DATA_ON_READ (0x800 | 0x20 | 0xe) |
#define | ITM_FUNCTION_EMIT_DATA_ON_WRITE (0x800 | 0x20 | 0xd) |
#define | ITM_FUNCTION_EMIT_PC_AND_DATA_ON_READ (0x800 | 0x30 | 0xe) |
#define | ITM_FUNCTION_EMIT_PC_AND_DATA_ON_WRITE (0x800 | 0x30 | 0xd) |
#define | ITM_port32(n) (*((volatile unsigned int *)(ITM_BASE_ADDR + 4 * n))) |
Write a 32-bit word to stimulus port n. More... | |
#define | ITM_send32Polling(n, x) |
Write a 32-bit word to stimulus port n with polling. More... | |
#define | ITM_port16(n) (*((volatile unsigned short *)(ITM_BASE_ADDR + 4 * n))) |
Write a 16-bit half word to stimulus port n. More... | |
#define | ITM_send16Polling(n, x) |
Write a 16-bit word to stimulus port n with polling. More... | |
#define | ITM_port8(n) (*((volatile unsigned char *)(ITM_BASE_ADDR + 4 * n))) |
Write a byte to stimulus port n. More... | |
#define | ITM_send8Polling(n, x) |
Write a 8-bit word to stimulus port n with polling. More... | |
Enumerations | |
enum | ITM_TPIU_PortFormat { ITM_TPIU_SWO_MANCHESTER = 0x00000001, ITM_TPIU_SWO_UART = 0x00000002 } |
enum | ITM_WatchpointAction { ITM_Disabled = (0x00), ITM_EmitPc = (0x30 | 0x4), ITM_EmitDataOnReadWrite = (0x800 | 0x20 | 0xc), ITM_SamplePcAndEmitDataOnReadWrite = (0x800 | 0x30 | 0x2), ITM_SampleDataOnRead = (0x800 | 0x20 | 0xe), ITM_SampleDataOnWrite = (0x800 | 0x20 | 0xd), ITM_SamplePcAndDataOnRead = (0x800 | 0x30 | 0xe), ITM_SamplePcAndDataOnWrite = (0x800 | 0x30 | 0xd) } |
Control the action taken by the DWT on comparator match. More... | |
enum | ITM_TimeStampPrescaler { ITM_TS_DIV_NONE = 0, ITM_TS_DIV_4 = 1, ITM_TS_DIV_16 = 2, ITM_TS_DIV_64 = 3 } |
Prescaler for ITM timestamp generation based on the trace packet reference clock. More... | |
enum | ITM_SyncPacketRate { ITM_SYNC_NONE = 0, ITM_SYNC_TAP_BIT24 = 1, ITM_SYNC_TAP_BIT26 = 2, ITM_SYNC_TAP_BIT28 = 3 } |
Synchronous packet generation rate based on cycles of CYCCNT This controls how often sync packets will be generated. The tap controls which bit transition in the counter triggers a packet. More... | |
Functions | |
bool | ITM_open (void) |
Open and configure the ITM, DWT, and TPIU. This includes muxing pins as needed. More... | |
void | ITM_close (void) |
void | ITM_sendBufferAtomic (const uint8_t port, const char *msg, size_t length) |
Write the contents of a buffer to the stimulus port, polling to ensure the port is available. More... | |
void | ITM_send32Atomic (uint8_t port, uint32_t value) |
Write a 32-bit word to the given stimulus port, polling to ensure the port is available. More... | |
void | ITM_send16Atomic (uint8_t port, uint16_t value) |
Write a 16-bit short to the given stimulus port, polling to ensure the port is available. More... | |
void | ITM_send8Atomic (uint8_t port, uint8_t value) |
Write an 8-bit byte to the given stimulus port, polling to ensure the port is available. More... | |
void | ITM_enableExceptionTrace (void) |
Enable exception tracing This will trigger the DWT to generate packets when the device enters or leaves an exception. The ITM will forward these packets to the TPIU to be sent to the debugger. More... | |
void | ITM_disableExceptionTrace (void) |
Disable exception tracing. More... | |
void | ITM_enablePCSampling (bool prescale1024, uint8_t postReset) |
Enable periodic sampling of the program counter using the DWT POSTCNT timer. More... | |
void | ITM_enableEventCounter (bool prescale1024, uint8_t postReset) |
Enable generation of event counter packets using the DWT POSTCNT timer. More... | |
void | ITM_disablePCAndEventSampling (void) |
Disable program counter and event sampling in the DWT. More... | |
void | ITM_enableTimestamps (ITM_TimeStampPrescaler tsPrescale, bool asyncMode) |
Enable the generation of local timestamp packets from the ITM module These are packets sent form the ITM that measure how long it has been since the previous timestamp. More... | |
void | ITM_enableSyncPackets (ITM_SyncPacketRate syncPacketRate) |
Enable the generation of synchronization packets from the ITM based on the CYCCNT counter. Synchronization packets can be used to recover bit-to-byte alignment information in a serial data stream. More... | |
bool | ITM_enableWatchpoint (ITM_WatchpointAction function, const uintptr_t address) |
Enable the watchpoint functionality using a DWT comparator. More... | |
void | ITM_flush (void) |
Flush the ITM in preparation for power off of CPU domain. More... | |
void | ITM_restore (void) |
Prepare the ITM hardware to return from power off of CPU domain This will reenable DWT features, re apply the ITM pin mux. More... | |
#define ITM_BASE_ADDR (0xE0000000) |
Base address of the Instrumentation Trace Macrocell (ITM) module.
#define ITM_DWT_BASE_ADDR (0xE0001000) |
Base address of the Debug Watchpoint and Trace (DWT) module.
#define ITM_SCS_BASE_ADDR (0xE000E000) |
Base address of the CPU_SCS module.
#define ITM_TPIU_BASE_ADDR (0xE0040000) |
Base address of the Trace Port Instrumentation Unit (TPIU) module.
#define ITM_LAR_UNLOCK (0xC5ACCE55) |
Value to unlock ARM debug modules. This value should be written to the Lock Access Registers (LAR) in order to enable their configuration and use.
#define ITM_FUNCTION_DISABLED (0x00) |
Device-specific values that implement the generic ITM-functions in ITM_WatchpointAction.
#define ITM_FUNCTION_EMIT_PC (0x30 | 0x4) |
#define ITM_FUNCTION_EMIT_DATA_ON_READ_WRITE (0x800 | 0x20 | 0xc) |
#define ITM_FUNCTION_EMIT_PC_ON_READ_WRITE (0x800 | 0x30 | 0x2) |
#define ITM_FUNCTION_EMIT_DATA_ON_READ (0x800 | 0x20 | 0xe) |
#define ITM_FUNCTION_EMIT_DATA_ON_WRITE (0x800 | 0x20 | 0xd) |
#define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_READ (0x800 | 0x30 | 0xe) |
#define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_WRITE (0x800 | 0x30 | 0xd) |
#define ITM_port32 | ( | n | ) | (*((volatile unsigned int *)(ITM_BASE_ADDR + 4 * n))) |
Write a 32-bit word to stimulus port n.
#define ITM_send32Polling | ( | n, | |
x | |||
) |
Write a 32-bit word to stimulus port n with polling.
#define ITM_port16 | ( | n | ) | (*((volatile unsigned short *)(ITM_BASE_ADDR + 4 * n))) |
Write a 16-bit half word to stimulus port n.
#define ITM_send16Polling | ( | n, | |
x | |||
) |
Write a 16-bit word to stimulus port n with polling.
#define ITM_port8 | ( | n | ) | (*((volatile unsigned char *)(ITM_BASE_ADDR + 4 * n))) |
Write a byte to stimulus port n.
#define ITM_send8Polling | ( | n, | |
x | |||
) |
enum ITM_TPIU_PortFormat |
enum ITM_WatchpointAction |
Control the action taken by the DWT on comparator match.
enum ITM_SyncPacketRate |
Synchronous packet generation rate based on cycles of CYCCNT This controls how often sync packets will be generated. The tap controls which bit transition in the counter triggers a packet.
Enumerator | |
---|---|
ITM_SYNC_NONE | Disabled |
ITM_SYNC_TAP_BIT24 | Tap the CYCCNT register at bit 24 |
ITM_SYNC_TAP_BIT26 | Tap the CYCCNT register at bit 26 |
ITM_SYNC_TAP_BIT28 | Tap the CYCCNT register at bit 28 |
bool ITM_open | ( | void | ) |
Open and configure the ITM, DWT, and TPIU. This includes muxing pins as needed.
void ITM_close | ( | void | ) |
Disable the ITM, when it is no longer in use, it will be shutdown. This will also turn off any additional features that were enabled such as PC sampling or interrupt tracing
void ITM_sendBufferAtomic | ( | const uint8_t | port, |
const char * | msg, | ||
size_t | length | ||
) |
Write the contents of a buffer to the stimulus port, polling to ensure the port is available.
port | The stimulus port to use |
msg | Data to send. |
length | length of buffer in bytes |
void ITM_send32Atomic | ( | uint8_t | port, |
uint32_t | value | ||
) |
Write a 32-bit word to the given stimulus port, polling to ensure the port is available.
port | The stimulus port to use |
value | The 32-bit value to write |
void ITM_send16Atomic | ( | uint8_t | port, |
uint16_t | value | ||
) |
Write a 16-bit short to the given stimulus port, polling to ensure the port is available.
port | The stimulus port to use |
value | The 16-bit value to write |
void ITM_send8Atomic | ( | uint8_t | port, |
uint8_t | value | ||
) |
Write an 8-bit byte to the given stimulus port, polling to ensure the port is available.
port | The stimulus port to use |
value | The 8-bit value to write |
void ITM_enableExceptionTrace | ( | void | ) |
Enable exception tracing This will trigger the DWT to generate packets when the device enters or leaves an exception. The ITM will forward these packets to the TPIU to be sent to the debugger.
void ITM_disableExceptionTrace | ( | void | ) |
Disable exception tracing.
void ITM_enablePCSampling | ( | bool | prescale1024, |
uint8_t | postReset | ||
) |
Enable periodic sampling of the program counter using the DWT POSTCNT timer.
prescale1024 | true: divide system clock by 1024 to generate POSTCNT false: divide system clock by 64 to generate POSTCNT |
postReset | 4-bit downcounter that is reloaded on POSTCNT expiration |
void ITM_enableEventCounter | ( | bool | prescale1024, |
uint8_t | postReset | ||
) |
Enable generation of event counter packets using the DWT POSTCNT timer.
prescale1024 | true: divide system clock by 1024 to generate POSTCNT false: divide system clock by 64 to generate POSTCNT |
postReset | 4-bit downcounter that is reloaded on POSTCNT expiration |
void ITM_disablePCAndEventSampling | ( | void | ) |
Disable program counter and event sampling in the DWT.
void ITM_enableTimestamps | ( | ITM_TimeStampPrescaler | tsPrescale, |
bool | asyncMode | ||
) |
Enable the generation of local timestamp packets from the ITM module These are packets sent form the ITM that measure how long it has been since the previous timestamp.
tsPrescale | Prescaler value for the timestamp clock. |
asyncMode | true: Synchronous mode - generate timestamps by dividing the system clock. false: Asynchronous mode - generate timestamps by dividing the TPIU clock. |
void ITM_enableSyncPackets | ( | ITM_SyncPacketRate | syncPacketRate | ) |
Enable the generation of synchronization packets from the ITM based on the CYCCNT counter. Synchronization packets can be used to recover bit-to-byte alignment information in a serial data stream.
syncPacketRate | Tap for CYCCNT. Controls the frequency of sync packets. |
bool ITM_enableWatchpoint | ( | ITM_WatchpointAction | function, |
const uintptr_t | address | ||
) |
Enable the watchpoint functionality using a DWT comparator.
function | The DWT_FUNCTION field to be programmed. This controls what data is emitted on comparator match see ITM_WatchpointAction for possible values |
address | The address for the comparator to match on |
void ITM_flush | ( | void | ) |
Flush the ITM in preparation for power off of CPU domain.
This will disable PC sampling, and other DWT features, flush the fifo and (if applicable) setup the PIN as a GPIO.
void ITM_restore | ( | void | ) |
Prepare the ITM hardware to return from power off of CPU domain This will reenable DWT features, re apply the ITM pin mux.