<!-- Start of markdown source --> # Introduction SWO Trace is a single pin trace interface that is part of the Cortex M Coresight components from ARM Ltd. It supports profiling hardware events such as periodic sampling of program counter, data variable reads and writes, interrupt entry and exit, counters as well as application generated software messages. It is also fully integrated into Code Composer Studio and supports the following Cortex M device families: <ul> <li>MSP432</li> <li>Tiva C (TM4C129 and TM4C123)</li> <li>CC26xx</li> <li>CC13xx</li> </ul> The ARM documentation contains additional details about the SWO Technology as part of the CoreSight: https://developer.arm.com/docs/ddi0314/h/serial-wire-output <font color="#f00000"><b>For previous versions, please check the </b></font>[SWO Trace CCSv9](emu_swo_trace_ccsv9.html). # Requirements per device family or board ## MSP432 Launchpad **Step 1:** Target Configuration The MSP432 Launchpad has an onboard XDS110 debug probe which supports SWO Trace. MSP432 supports 2 debug protocols; JTAG and SWD. SWO Trace for MSP432 is output on the TDO pin in SWD mode only. As such SWO Trace is not available in JTAG mode. To use SWO Trace create your target configuration with SWD as the debug protocol with TDO connection to the Aux COM port as indicated in the snapshot below: ![](./images/emu_swo_trace_ccsv9_msp432-config.jpg) **Step 2:** Basic Setup Once the target configuration is selected, launch the debug session and load the application. [[b Note: SWO Trace requires trace clock setup which is dependent on the system clock of the target. If your application configures the system clock after main, run to the line after the system clock configuration and then we are ready to launch the trace capture. ]] In the code snippet below, as indicated in line 145 the subsequent lines configure the main clock. Run to the highlighted line (line 152) and then setup the trace capture. ![](./images/emu_swo_trace_ccsv9_msp432-code.jpg) **Step 3:** Start Trace Capture Trace can be configured by going to menu Tools &rarr; Code Analysis &rarr; Event Analysis. CCS exposes the trace capabilities as 4 pre-configured Usecases: <ol> <li>Statistical Function Profile: Periodic program counter samples.</li> <li>Exception Profile: Interrupt entry exit and preemption.</li> <li>Variable Profile: Variable reads and writes.</li> <li>Message Logging: Software messages.</li> </ol> For additional details please see the [Usecases](#usecases) section below. ## Tiva/TM4C **Step 1:** Target Configuration The Tiva/TM4C launchpads have the onboard ICDI debug probe that does not support SWO Trace. Instead use an external XDS200 debug probe. The XDS200 debug probe supports JTAG and SWD mode for Tiva/TM4C devices. SWO Trace is output on the TDO pin in SWD mode only. SWO Trace is not available in JTAG mode. To use SWO Trace create the target configuration as indicated in the snapshot below with SWD as the debug protocol and User COM port routed to TDO pin. ![](./images/emu_swo_trace_ccsv9_tivac-config.jpg) **Step 2: Basic Setup** Once the target configuration is selected, launch the debug session and load the application. [[b Note: SWO Trace requires trace clock setup which is dependent on the system clock of the target. If your application configures the system clock after main, run to the line after the system clock configuration and then we are ready to launch the trace capture. ]] In the code snippet below, line 408 configures the system clock. Run to the highlighted line (line 415) and then setup the trace capture. ![](./images/emu_swo_trace_ccsv9_tivac-code.jpg) **Step 3: Start Trace Capture** Trace can be configured by going to menu Tools &rarr; Code Analysis &rarr; Event Analysis. CCS exposes the trace capabilities as 4 pre-configured Usecases: <ol> <li>Statistical Function Profile: Periodic program counter samples.</li> <li>Exception Profile: Interrupt entry exit and preemption.</li> <li>Variable Profile: Variable reads and writes.</li> <li>Message Logging: Software messages.</li> </ol> For additional details please see the [Usecases](#usecases) section below. ## CC26xx and CC13xx **Step 1:** Target Configuration The CC26xx and CC13xx SensorTag development kits can be used with the optional Debugger DevPack (CC_DEVPACK_DEBUG) which is an XDS110 class debug probe that supports SWO Trace. These device families require the application to route the SWO Trace to a GPIO pin. The application will need to route the SWO Trace to TDO pin by including the line below in the application: ```c // Map Serial Wire Viewer to JTAG TDO pin IOCPortConfigureSet(IOID_16, IOC_PORT_MCU_SWV, IOC_STD_OUTPUT); ``` And including the header file: ```c #include "ioc.h" ``` This header file can be found in the SimpleLink SDK directory: <tt>&lt;SIMPLELINK SDK ROOT&gt;/source/ti/devices/&lt;DEVICE&gt;/driverlib</tt> This path must be added to the list of include search paths under the "Include Options" compiler properties in the project properties. [[b Note: If you are using one of the SimpleLink SDK examples, one option is to add the above IOCPortConfigureSet call to the &lt;BOARD&gt;\_initGeneral (ex. CC1310_LAUNCHXL_initGeneral() ) function in the device board file (ex. CC1310_LAUNCHXL.c). This file is responsible for setting up board specific items and already includes ioc.h, hence no need to have a statement to include the header file. The project properties already have the necessary include paths configured so no need to add any additional include search path to the project properties. ]] Now, to use SWO Trace create the target configuration as indicated in the snapshot below with debug protocol as 2-pin cJTAG and TDO routed to Aux COM. ![](./images/emu_swo_trace_ccsv9_cc2650-config.jpg) **Step 2: Basic Setup** Once the target configuration is selected, launch the debug session and load the application. [[b Note: SWO Trace requires trace clock setup which is dependent on the system clock of the target. If your application halts at main and the application configures the system clock after main, run to the line after the system clock configuration and then we are ready to launch the trace capture. ]] **Step 3:** Start Trace Capture Trace can be configured by going to menu Tools &rarr; Code Analysis &rarr; Event Analysis. CCS exposes the trace capabilities as 4 pre-configured Usecases: <ol> <li>Statistical Function Profile: Periodic program counter samples.</li> <li>Exception Profile: Interrupt entry exit and preemption.</li> <li>Variable Profile: Variable reads and writes.</li> <li>Message Logging: Software messages.</li> </ol> For additional details, please see the [Usecases](#usecases) section below. # Usecases CCS exposes trace capabilities in the form of usecases. SWO Trace has 4 pre-configured usecases: <ol> <li>Statistical Function Profile</li> <li>Exception Profile</li> <li>Variable Profile</li> <li>Message Logging</li> </ol> To select a usecase, go to the menu Tools &rarr; Code Analysis &rarr; Event Analysis. A new view is opened and **Step 1** contains a list of all usecases and **Step 2** contains advanced settings in case there are multiple boards connected. ![](./images/emu_swo_trace_usecases_list.png) In case cJTAG is used (most of the CC13xx and CC26xx devices), the view will show a message box with configuration details that must be added to the project, as shown below: ![](./images/emu_swo_trace_cjtag.png) Each usecase is presented in detail in the following sub sections. ## Statistical Function Profile Statistical function profile is useful for analyzing code execution. It brings to light the execution intensive functions which could either be smaller functions occurring frequently or larger functions taking more execution time. The PC sample hardware events are generated by the DWT (Data Watchpoint and Trace Unit) and can be configured to output PC samples periodically at configurable intervals. When the Statistical Function Profile usecase is selected, the **Sampling Interval** option is shown. This option controls how frequently the Program Counter (PC) register is sampled. The lowest interval is 64 processor clocks. ![](./images/emu_swo_trace_stat-func-ui.png) [[b Note: Smaller intervals yield higher density trace which could cause overflows and packet loss if the data cannot be drained fast enough. If the trace data shows overflows increase the interval and try again. ]] Once the **OK** button is clicked, the Trace viewer with its 5 tabs replace the previous setup view. For this particular usecase, only the Statistical Function Profile and the Raw Data are of interest. The **Raw Data** tab shows the information sent by the target without processing, while the Statistical Function Profile shows analysis of the PC samples in terms of function execution. When the core is put to run the trace data gets processed and shown at specific intervals - an update also happens when the core is halted either due to a breakpoint or manually. The analysis window shows the percentage of time the various functions were encountered. The following snapshot was captured using the onboard XDS110 debug probe on a MSP432P4111 launchpad with the target executing the OutOfBox demo application. ![](./images/emu_swo_trace_stat-func-views.png) The **Raw Data** tab also outputs messages indicating if the core is in sleep executing a wfi or wfe. ## Exception Profile Exception Profile can be used to determine how and at what frequency exceptions are happening on the system. Exception entry, exit and preemption information are all listed in the hardware events are generated by the DWT (Data Watchpoint and Trace) unit. There are no configurable parameters for this usecase as indicated in the snapshot below. ![](./images/emu_swo_trace_exception-ui.png) Once the **OK** button is clicked, the Trace viewer with its 5 tabs replaces the previous setup view. For this particular usecase, only the **Exception Profile** and the **Raw Data** tabs are of interest. The **Raw Data** tab shows the information sent by the target without processing, while the **Exception Profile** tab shows the timeline of the exception events. When the core is put to run, the trace data gets processed and the values are shown in both graph of exception ocurrences delimited by the Entry and Exit events and a tabular view with all captured data samples and its values - an update also happens when the core is halted either due to a breakpoint or manually. ![](./images/emu_swo_trace_exception-ui-view.png) ## Variable Profile Variable Profile can be used to profile variable reads and writes. Data variable read and write events are generated by the DWT (Data Watchpoint and Trace) Unit. The trace hardware outputs a packet every time the variable is read and/or written with the corresponding value and so this usecase is not statistical. When this usecase is selected in CCS, the tab is expanded and prompt for the address. The hex value of the address can be entered directly or, if symbols are loaded, a variable name can be typed directly. ![](./images/emu_swo_trace_data-var-ui.png) Once the **OK** button is clicked, the Trace viewer with its 5 tabs replaces the previous setup view. For this particular usecase, only the **Variable Profile** and the **Raw Data** tabs are of interest. The **Raw Data** tab shows the information sent by the target without processing, while the **Variable Profile** tab shows the read and write events. When the core is put to run, the trace data gets processed and the values are shown in both a graph of reads and writes and a tabular view with all captured data samples and its values - an update also happens when the core is halted either due to a breakpoint or manually. ![](./images/emu_swo_trace_data-var-views.png) ## Message Logging Messages can be directly transferred by the application to the host, just like a printf() but using the trace channel instead of the Console I/O. Message Logging is issued through the ITM (Instrumentation Trace Macrocell). The ITM in Cortex M has 32 stimulus ports. Writes to the stimulus ports result in a data packet of size word, half-word or byte depending on the size of the data written. When this usecase is selected in CCS, the tab is expanded and all the stimulus ports are shown with switches for binary or data formatted as characters. ![](./images/emu_swo_trace_message-ui.png) Once the **OK** button is clicked, the Trace viewer with its 5 tabs replaces the previous setup view. For this particular usecase, only the **Message Logging** and the **Raw Data** tabs are of interest. The messages can be displayed all together or separately by checking the box **Display each channel on a separate line with timestamp**. In the example below, the channels 1 and 3 have the character filter enabled, while channels 2 and 4 have the binary data directly displayed (in decimal format). ![](./images/emu_swo_trace_message-ui-view.png) Sample code with APIs to use ITM can be found below: ```c //***************************************************************************** // // main.c template // //**************************************************************************** #include &lt;stdio.h&gt; #include &lt;stdint.h&gt; #include &lt;stdbool.h&gt; const unsigned ITM_BASE_ADDRESS = 0xE0000000; const unsigned ITM_NUM_PORTS = 32; const unsigned NUM_TRIALS = 2; typedef volatile unsigned* ITM_port_t; void delay(unsigned num_loops) { unsigned i; for (i=0; i&lt;num_loops; i++) { asm (&quot;NOP&quot;); } } void port_wait(ITM_port_t port) { delay(10); /* Wait while fifo ready */ while (*port == 0); } /* Send a nul terminated string to the port */ void ITM_put_string(ITM_port_t port, const char* data) { unsigned datapos = 0; unsigned portpos = 0; unsigned portdata = 0; while(&#39;\0&#39; != data[datapos]) { port_wait(port); portdata = 0; /* Get the next 4 bytes of data */ for (portpos=0; portpos&lt;4; ++portpos) { portdata |= data[datapos] &lt;&lt; (8*portpos); if (&#39;\0&#39; != data[datapos]) { ++datapos; } } /* Write the next 4 bytes of data */ *port = portdata; } } /* Send a 32 bit value to the port */ void ITM_put_32(ITM_port_t port, unsigned data) { port_wait(port); *port = data; } /* Send a 16 bit value to the port */ void ITM_put_16(ITM_port_t port, unsigned short data) { /* Cast port for 16-bit data */ volatile unsigned short* myport = (volatile unsigned short*)port; port_wait(port); *myport = data; } /* Send a 8 bit value to the port */ void ITM_put_08(ITM_port_t port, unsigned char data) { /* Cast port for 8-bit data */ volatile unsigned char* myport = (volatile unsigned char*)port; port_wait(port); *myport = data; } void main(void) { unsigned trial_num, port_num = 1, port_address; ITM_port_t port; for (trial_num=0; trial_num &lt; 10; ++trial_num) { for (port_num=1; port_num&lt;ITM_NUM_PORTS; ++port_num) { // Send text to port 0 ITM_put_string((ITM_port_t)ITM_BASE_ADDRESS, &quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&amp;*()-_=+[{]}\\|;:&#39;\&quot;,&lt;.&gt;/? &quot;); ITM_put_string((ITM_port_t)ITM_BASE_ADDRESS, &quot;hello\nworld&quot;); delay(100); // Get this port address port_address = ITM_BASE_ADDRESS + (4*port_num); port = (ITM_port_t)port_address; // Send numeric data to this ports ITM_put_32(port, 33); delay(100); ITM_put_32(port, 0x12345678); delay(100); ITM_put_16(port, 33); delay(100); ITM_put_16(port, 0x9abc); delay(100); ITM_put_08(port, 33); delay(100); ITM_put_08(port, 0xde); delay(100); ITM_put_string((ITM_port_t)ITM_BASE_ADDRESS, &quot;end\n&quot;); delay(10000); } delay(10000); } } ``` # Troubleshooting <strong><font color="#F000F0">1.</font> I am seeing overflow packets in the trace data stream. How do I avoid them?</strong> The first setting to change is the timestamp resolution. The timestamp resolution can be set at 4 different levels; divide by 1 (no prescale), divide by 4, divide by 16 and divide by 64. Divide by 1 gives the finest granularity and divide by 64 the lowest granularity but also fewer trace packets. To change the timestamp granularity, at **Step 1** of the main Event Analysis Setup view, select the drop down **Common Configuration** and choose a higher resolution value. ![](./images/emu_swo_trace_receiver-timestamp.jpg) If you are using Statistical Function profile, then the density of the stream can be reduced by increasing the "Sampling interval" in the usecase setup UI. <br> <br> <hr> <!-- <strong><font color="#F000F0">2.</font> When I start a usecase I get an error message indicating that the System clock could not be determined and to enter it manually.</strong> For some devices the system clock cannot be determined because of certain clock configuration settings such as external crystal dependency. To set the system clock manually, click on the "Advanced Settings" button in the Usecase UI and then select the Receiver. Drill down to the UART Options section and change the setting for Clock frequency from "Auto" to "Manual" as indicated in the snapshot below. A text box appears. Specify the System clock in Hz in the text box. ![](./images/emu_swo_trace_ccsv9_receive_settings.jpg) <strong><font color="#F000F0">3.</font> How do I setup SWO Trace for a particular baud rate?</strong> By default CCS will try and configure the hardware for the highest possible baud rate. However if you need to specify your own baud rate you can override the automatic configuration and enter it manually. Click on the "Advanced Settings" button in the Usecase UI and then select the Receiver in the Advanced Properties button. Drill down to the "UART Options" group and select the "Clock frequency" entry. Change the setting from "Auto" to "Manual". An input text box appears. Enter the system clock in Hz. Now drill down to the "SWO Selection" section and select the "Prescalar" entry. Change the setting from "Auto" to "Manual". An input text box appears. Enter a divide by factor to divide the clock to the desired baud rate based on the equation below: <code> BaudRate = Clock frequency / (Prescalar + 1) For example, if System clock frequency is 120Mhz, and desired baud rate is 115200, then based on the formula above: Prescalar = (Clock frequency/BaudRate) - 1 = (120 * 1000 * 1000 / 115200) - 1 = 1041.667 - 1 = 1041 (rounded to the nearest decimal) </code> Enter the value <strong>1041</strong> in the Prescalar input text box. --> <!-- End of markdown source --> <div id="footer"></div>