ITM.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2024, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*!*****************************************************************************
33  * @file ITM.h
34  * @brief ITM driver header
35  *
36  * @anchor ti_drivers_ITM_Overview
37  * <h3> Overview </h3>
38  * This driver implements APIs to configure and control the ARM Instrumentation
39  * Trace Macrocell (ITM), Debug Watchpoint and Trace (DWT), and Trace Port
40  * Instrumentation Unit (TPIU) IPs to realize non-intrusive software logging
41  * and runtime trace.
42  *
43  * # Overview <a name="overview"></a>
44  * The ITM software module provides application level APIs for the non-invasive
45  * debug capabilities of the ARM Cortex-M family. This includes the following
46  * hardware modules:
47  *
48  * - Instrumentation Trace Macrocell (ITM)
49  * - Debug Watchpoint and Trace (DWT)
50  * - Trace Port Instrumentation Unit (TPIU)
51  *
52  * At a high level, the DWT provides watchpoint, data trace, and program
53  * counter sampling. The ITM provides memory mapped registers for low-intrusion
54  * software profiling. The TPIU provides an external interface for the ITM and
55  * DWT. Further details can be found in the
56  * [ARMv7-M Architecture Reference Manual](https://static.docs.arm.com/ddi0403/e/DDI0403E_d_armv7m_arm.pdf)
57  *
58  * <h3> Limitations and Constraints </h3>
59  * The driver is is designed with the following constraints in mind:
60  * - ITM is designed as a singleton. This means that a single instance is
61  * shared across all clients
62  * - The parallel TracePort mode of the TPIU is not supported, only
63  * serial protocols are considered
64  * - The ITM hardware is configured via firmware on the DUT.
65  * Log records can be read independent of any IDE or debugger configuration.
66  * This means that if the IDE debug system configures the ITM, it should
67  * be turned off.
68  * - In Code Composer Studio, it is not currently possible to disable
69  * the debugger configuration mentioned above. No ITM output will be visible
70  * while the IDE's debugger is connected. Please flash your firmware, then
71  * disconnect and reset the device to see ITM data on the serial port.
72  *
73  * @anchor ti_drivers_ITM_Setup
74  * <h3> Setup </h3>
75  * The ITM is configured via hardware attributes stored in the hardware
76  * attributes structure. This structure contains a common portion that is used
77  * for all drivers. This structure may be extended for some devices such as
78  * CC26XX.
79  *
80  * <h3> Opening the driver </h3>
81  * Unlike other drivers, the ITM is intended to be a singleton.
82  * This means that @ref ITM_open can be called multiple times.
83  * The ITM will only be configured the first time open is called.
84  *
85  * Furthermore, helper functions for features such as PC sampling must coherent
86  * across clients. The driver offers no protection against mismatched
87  * configuration.
88  *
89  * The open call will enable ITM as well as the necessary stimulus ports.
90  * It will setup the TPIU for necessary baudrate and serial format.
91  *
92  * @anchor ti_drivers_ITM_PinMux
93  * <h3> Pin Muxing </h3>
94  * As the ITM driver is primarily interfacing to ARM defined IP, it is almost
95  * entirely common across all supported devices. The only specifics are pin
96  * muxing of the SWO pin. See the table below for some notes
97 
98  * | Device Family | Debug Protocol | Muxing | Configurable? |
99  * |---------------|----------------|-----------------|---------------|
100  * | CC13XX/CC26XX | JTAG/cJTAG | Any pin | Y |
101  *
102  * Device specific pin muxing is done by the device specific ITM backend
103  * implementation.
104  *
105  * @anchor ti_drivers_ITM_SwMessages
106  * <h3> Software Messages </h3>
107  * The ITM stimulus ports enable serialization of application data with low
108  * overhead. There are multiple ports available, they are selectable via
109  * software.
110  *
111  * Data written to the software stimulus ports is serialized by the TPIU
112  * and wrapped in the SWIT packet format. This packet format is standardized
113  * by ARM and described in [ARMv7-M Architecture Reference
114  Manual](https://static.docs.arm.com/ddi0403/e/DDI0403E_d_armv7m_arm.pdf)
115  *
116  * There are three tiers of access to the stimulus ports. In the table below,
117  * polled access means that the API/macro will poll the port's busy flag
118  * before writing. This is done to prevent silent data loss that
119  * occurs when writing to a port that is not ready. Actual serialization of the
120  * data will occur later inside the TPIU.
121  *
122  * - ITM_PortX - Macro to write or read to the port, doesn't poll before
123  * - ITM_sendXPolling - Macro that polls and writes to the port
124  * - ITM_sendXAtomic - Function that calls ITM_sendXPolling with interrupts
125  * disabled
126  *
127  * It is up the the application writer to understand the tradeoff associated
128  * with each of these and select the correct one.
129  *
130  * <h3> DWT Features </h3>
131  * The Data Watchpoint and Trace (DWT) module is capable of many
132  * instrumentation features such as
133  *
134  * | Feature | ITM API |
135  * |--------------------------|-------------------------------------|
136  * | Exception trace | @ref ITM_enableExceptionTrace |
137  * | Program Counter sampling | @ref ITM_enablePCSampling |
138  * | Event counting | @ref ITM_enableEventCounter |
139  * | Synchronization packets | @ref ITM_enableSyncPackets |
140  *
141  *
142  * Data generated by the DWT is serialized via the TPIU. DWT packet formats
143  * are defined in the ARMv7-M Architecture Reference Manual referenced above
144  *
145  * <h3>Flush </h3>
146  * The ITM/DWT/TPIU hardware resides in the CPU power domain. This means that
147  * whenever the CPU domain is powered down, ITM will power down.
148  * Powering down when data is inside in the TPIU can result in lost data.
149  * In order to prevent dataloss, the device's power policy will flush the
150  * ITM before powering down the CPU domain. When returning from sleep, the
151  * power policy will restore the ITM. This is achieved using the
152  * @ref ITM_flush and @ref ITM_restore.
153  *
154  * These functions are weakly defined as empty functions. This reduces the
155  * overhead in the power policy when ITM is not enabled. These weak functions
156  * are overridden by syscfg when ITM is enabled.
157  *
158  */
159 
160 #ifndef ti_drivers_ITM__include
161 #define ti_drivers_ITM__include
162 
163 #include <stddef.h>
164 #include <stdbool.h>
165 #include <stdint.h>
166 
167 #include <ti/devices/DeviceFamily.h>
168 
169 #ifdef __cplusplus
170 extern "C" {
171 #endif
172 
177 #define ITM_BASE_ADDR (0xE0000000)
178 
183 #define ITM_DWT_BASE_ADDR (0xE0001000)
184 
189 #define ITM_SCS_BASE_ADDR (0xE000E000)
190 
195 #define ITM_TPIU_BASE_ADDR (0xE0040000)
196 
203 #define ITM_LAR_UNLOCK (0xC5ACCE55)
204 
210 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC13X4_CC26X3_CC26X4 || \
211  DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
212  #define ITM_FUNCTION_DISABLED (0x00)
213  #define ITM_FUNCTION_EMIT_PC (0x30 | 0x4)
214  #define ITM_FUNCTION_EMIT_DATA_ON_READ_WRITE (0x800 | 0x20 | 0xc)
215  #define ITM_FUNCTION_EMIT_PC_ON_READ_WRITE (0x800 | 0x30 | 0x2)
216  #define ITM_FUNCTION_EMIT_DATA_ON_READ (0x800 | 0x20 | 0xe)
217  #define ITM_FUNCTION_EMIT_DATA_ON_WRITE (0x800 | 0x20 | 0xd)
218  #define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_READ (0x800 | 0x30 | 0xe)
219  #define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_WRITE (0x800 | 0x30 | 0xd)
220 #else
221  #define ITM_FUNCTION_DISABLED 0x00
222  #define ITM_FUNCTION_EMIT_PC 0x01
223  #define ITM_FUNCTION_EMIT_DATA_ON_READ_WRITE 0x02
224  #define ITM_FUNCTION_EMIT_PC_ON_READ_WRITE 0x03
225  #define ITM_FUNCTION_EMIT_DATA_ON_READ 0x0C
226  #define ITM_FUNCTION_EMIT_DATA_ON_WRITE 0x0D
227  #define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_READ 0x0E
228  #define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_WRITE 0x0F
229 #endif
230 
237 #define ITM_port32(n) (*((volatile unsigned int *)(ITM_BASE_ADDR + 4 * n)))
238 
239 /* The do {} while() loops below are to protect the macros so that they're
240  * evaluated correctly regardless of the call site. They do not have any
241  * function besides ensuring that the syntax is preserved correctly by the pre
242  * processor.
243  */
250 #define ITM_send32Polling(n, x) \
251  do \
252  { \
253  while (0 == ITM_port32(n)) \
254  ; \
255  ITM_port32(n) = x; \
256  } while (0)
257 
263 #define ITM_port16(n) (*((volatile unsigned short *)(ITM_BASE_ADDR + 4 * n)))
264 
271 #define ITM_send16Polling(n, x) \
272  do \
273  { \
274  while (0 == ITM_port16(n)) \
275  ; \
276  ITM_port16(n) = x; \
277  } while (0)
278 
284 #define ITM_port8(n) (*((volatile unsigned char *)(ITM_BASE_ADDR + 4 * n)))
285 
292 #define ITM_send8Polling(n, x) \
293  do \
294  { \
295  while (0 == ITM_port8(n)) \
296  ; \
297  ITM_port8(n) = x; \
298  } while (0)
299 
300 typedef enum
301 {
302  ITM_TPIU_SWO_MANCHESTER = 0x00000001,
303  ITM_TPIU_SWO_UART = 0x00000002,
305 
307 /* This enables a common defintion of the hwAttrs structure that can be easily
308  * extended by the device specific implementations. This structure defintion
309  * must be the first line of any device specific structure
310  */
311 #define ITM_BASE_HWATTRS \
312  ITM_TPIU_PortFormat format; /* Wire interface used by TPIU */ \
313  uint32_t traceEnable; /* Bitmask of enabled stimulus ports */ \
314  uint32_t tpiuPrescaler; /* Baudrate to be used by the TPIU */ \
315  uint32_t fullPacketInCycles; /* Cycles in a full word */ \
316 
324 typedef struct
325 {
326  ITM_BASE_HWATTRS
327 } ITM_HWAttrs;
328 
332 typedef enum
333 {
344 
349 typedef enum
350 {
361 typedef enum
362 {
368 
376 extern bool ITM_open(void);
377 
385 extern void ITM_close(void);
386 
398 extern void ITM_sendBufferAtomic(const uint8_t port, const char *msg, size_t length);
399 
407 extern void ITM_send32Atomic(uint8_t port, uint32_t value);
408 
416 extern void ITM_send16Atomic(uint8_t port, uint16_t value);
417 
425 extern void ITM_send8Atomic(uint8_t port, uint8_t value);
426 
434 extern void ITM_enableExceptionTrace(void);
435 
442 extern void ITM_disableExceptionTrace(void);
443 
458 extern void ITM_enablePCSampling(bool prescale1024, uint8_t postReset);
459 
472 extern void ITM_enableEventCounter(bool prescale1024, uint8_t postReset);
473 
480 extern void ITM_disablePCAndEventSampling(void);
481 
493 extern void ITM_enableTimestamps(ITM_TimeStampPrescaler tsPrescale, bool asyncMode);
494 
505 extern void ITM_enableSyncPackets(ITM_SyncPacketRate syncPacketRate);
506 
517 extern bool ITM_enableWatchpoint(ITM_WatchpointAction function, const uintptr_t address);
518 
533 extern void __attribute__((weak)) ITM_flush(void);
534 
546 extern void __attribute__((weak)) ITM_restore(void);
547 
548 #ifdef __cplusplus
549 }
550 #endif
551 
552 #endif /* ti_drivers_ITM__include */
void ITM_enableEventCounter(bool prescale1024, uint8_t postReset)
Enable generation of event counter packets using the DWT POSTCNT timer.
#define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_READ
Definition: ITM.h:218
bool ITM_open(void)
Open and configure the ITM, DWT, and TPIU. This includes muxing pins as needed.
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.
Definition: ITM.h:363
void ITM_enableSyncPackets(ITM_SyncPacketRate syncPacketRate)
Enable the generation of synchronization packets from the ITM based on the CYCCNT counter...
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 Hardware Attributes.
Definition: ITM.h:324
void ITM_enableExceptionTrace(void)
Enable exception tracing This will trigger the DWT to generate packets when the device enters or leav...
Definition: ITM.h:342
Definition: ITM.h:351
#define ITM_FUNCTION_EMIT_DATA_ON_READ
Definition: ITM.h:216
ITM_SyncPacketRate
Synchronous packet generation rate based on cycles of CYCCNT This controls how often sync packets wil...
Definition: ITM.h:361
Definition: ITM.h:365
Definition: ITM.h:352
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.
ITM_TPIU_PortFormat
Definition: ITM.h:300
void ITM_disableExceptionTrace(void)
Disable exception tracing.
bool ITM_enableWatchpoint(ITM_WatchpointAction function, const uintptr_t address)
Enable the watchpoint functionality using a DWT comparator.
void ITM_enablePCSampling(bool prescale1024, uint8_t postReset)
Enable periodic sampling of the program counter using the DWT POSTCNT timer.
Definition: ITM.h:364
Definition: ITM.h:354
#define ITM_FUNCTION_EMIT_DATA_ON_READ_WRITE
Definition: ITM.h:214
Definition: ITM.h:334
#define ITM_FUNCTION_DISABLED
Device-specific values that implement the generic ITM-functions in ITM_WatchpointAction.
Definition: ITM.h:212
Definition: ITM.h:353
Definition: ITM.h:302
ITM_WatchpointAction
Control the action taken by the DWT on comparator match.
Definition: ITM.h:332
void ITM_close(void)
Definition: ITM.h:335
#define ITM_FUNCTION_EMIT_PC_ON_READ_WRITE
Definition: ITM.h:215
ITM_TimeStampPrescaler
Prescaler for ITM timestamp generation based on the trace packet reference clock. ...
Definition: ITM.h:349
Definition: ITM.h:303
Definition: ITM.h:341
#define ITM_FUNCTION_EMIT_PC
Definition: ITM.h:213
#define ITM_FUNCTION_EMIT_PC_AND_DATA_ON_WRITE
Definition: ITM.h:219
void ITM_restore(void)
Prepare the ITM hardware to return from power off of CPU domain This will reenable DWT features...
Definition: ITM.h:340
void ITM_flush(void)
Flush the ITM in preparation for power off of CPU domain.
Definition: ITM.h:336
Definition: ITM.h:366
#define ITM_FUNCTION_EMIT_DATA_ON_WRITE
Definition: ITM.h:217
void ITM_disablePCAndEventSampling(void)
Disable program counter and event sampling in the DWT.
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...
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.
Definition: ITM.h:339
© Copyright 1995-2024, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale