SWO is a datastream that comes out of a single pin when the debug interface is in SWD mode. It can be encoded either using NRZ (UART) or RZ (Manchester) formats. The pin is a dedicated one that would be used for TDO when the debug interface is in JTAG mode. On the STM32 it's port PB3. When in NRZ mode the SWO data rate that comes out of the chip _must_ match the rate that the debugger expects. By default on BMP the baudrate is 2.25MBps but that can be changed as an optional parameter to the monitor traceswo command, like this; monitor traceswo 115200 ....would set the swo output at the low speed of 115kbps. We are constrained on maximum input speed by both the capabilities of the BMP STM32F103 USART and the ability to get the packets back out over the USB link. The UART baudrate is set by b=(72x10^6)/(16*d)...so for d=1 that means a maximum speed of 4.5Mbps. For continious streaming that turns out to be _too_ fast for the USB link, so the next available option is the 2.25Mbps that we use. ....you can safely use the 4.5Mbps setting if your debug data is bursty, or if you're using a different CPU to the STM32F103 as your BMP host, but you potentially run the risk of losing packets if you have long runs of sending which the usb cannot flush in time (there's a 12K buffer, so the it is a pretty long run before it becomes a problem). Note that the baudrate equation means there are only certain speeds available. The highest half dozen are; 1 4.50 Mbps 2 2.25 Mbps 3 1.50 Mbps 4 1.125 Mbps 5 0.900 Mbps 6 0.750 Mbps ...the USART will cope with some timing slip, but it's advisible to stay as close to these values as you can. As the speed comes down the spread between each valid value so mis-timing is less of an issue. The 'monitor traceswo ' command will automatically find the closest divisor to the value you set for the speed, so be aware the error could be significant. Depending on what you're using to wake up SWO on the target side, you may need code to get it into the correct mode and emitting data. You can do that via gdb direct memory accesses, or from program code. An example for a STM32F103 for the UART (NRZ) data format that we use; /* STM32 specific configuration to enable the TRACESWO IO pin */ RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; AFIO->MAPR |= (2 << 24); // Disable JTAG to release TRACESWO DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; // Enable IO trace pins *((volatile unsigned *)(0xE0040010)) = 31; // Output bits at 72000000/(31+1)=2.25MHz. *((volatile unsigned *)(0xE00400F0)) = 2; // Use Async mode (1 for RZ/Manchester) *((volatile unsigned *)(0xE0040304)) = 0; // Disable formatter /* Configure instrumentation trace macroblock */ ITM->LAR = 0xC5ACCE55; ITM->TCR = 0x00010005; ITM->TER = 0xFFFFFFFF; // Enable all stimulus ports Code for the STM32L476 might look like: #define BAUDRATE 115200 DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; /* Enable IO pins for Async trace */ uint32_t divisor, clk_frequency; clk_frequency = NutGetCpuClock(); divisor = clk_frequency / BAUDRATE; divisor--; TPI->CSPSR = 1; /* port size = 1 bit */ TPI->ACPR = divisor; TPI->SPPR = 2; /*Use Async mode pin protocol */ TPI->FFCR = 0x00; /* Bypass the TPIU formatter and send output directly*/ /* Configure Trace Port Interface Unit */ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Enable access to registers DWT->CTRL = 0x400003FE; // DWT needs to provide sync for ITM ITM->LAR = 0xC5ACCE55; // Allow access to the Control Register ITM->TPR = 0x0000000F; // Trace access privilege from user level code, please ITM->TCR = 0x0001000D; // ITM_TCR_TraceBusID_Msk | ITM_TCR_DWTENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_ITMENA_Msk ITM->TER = 1; // Only Enable stimulus port 1 while(1) { for (uint32_t i = 'A'; i <= 'Z'; i++) { ITM_SendChar(i); NutSleep(1); } } If you're using RZ mode (e.g. on a genuine BMP) then you will need the trace output speed to be quite a lot lower...in the order of 200kHz by means of changing the divisor to something like 359. That's because the STM32F103 doesn't have a dedicated RZ decoder so it all has to be done in software. The advantage of RZ is that the probe can adapt to the speed of the target, so you don't have to set the speed on the probe in the monitor traceswo command, and it will be tolerant of different speeds. The SWO data appears on USB Interface 5, Endpoint 5. SWOListen ========= A program swolisten.c is found in ./scripts which will listen to this endpoint, decode the datastream, and output it to a set of unix fifos which can then be used as the input to other programs (e.g. cat, or something more sophisticated like gnuplot, octave or whatever). This program doesn't care if the data originates from a RZ or NRZ port, or at what speed. Note that swolisten can be used with either BMP firmware, or with a conventional TTL serial dongle. See at the bottom of this file for information on how to use a dongle. The command line to build the swolisten tool is; gcc -I /usr/local/include/libusb-1.0 -L /usr/local/lib -lusb-1.0 swolisten.c -o swolisten For Opensuse: gcc -I /usr/include/libusb-1.0 -lusb-1.0 swolisten.c swolisten -std=gnu99 -g -Og ...you will obviously need to change the paths to your libusb files. Attach to BMP to your PC: Start gdb: "arm-none-eabi-gdb" Choose bmp as target, like: "target extended /dev/ttyACM0(*)" Start SWO output: "mon traceswo" If async SWO is used, give the baudrate your device sends out as argument. 2.25 MBaud is the default, for the STM32L476 example above the command would be: "mon traceswo 115200(*)". Scan the SWD "mon swdp_scan" Attach to the device: : "attach 1" Start the program: "r". (*) Your milage may vary Now start swolisten without further options. By default the tool will create fifos for the first 32 channels in a directory swo (which you will need to create) as follows; >ls swo/ chan00 chan02 chan04 chan06 chan08 chan0A chan0C chan0E chan10 chan12 chan14 chan16 chan18 chan1A chan1C chan1E chan01 chan03 chan05 chan07 chan09 chan0B chan0D chan0F chan11 chan13 chan15 chan17 chan19 chan1B chan1D chan1F >cat swo/channel0 <> With the F103 and L476 examples above, an endless stream of "ABCDEFGHIJKLMNOPQRSTUVWXYZ" should be seen. During reset of the target device, no output will appear, but with release of reset output restarts. Information about command line options can be found with the -h option. swolisten is specifically designed to be 'hardy' to probe and target disconnects and restarts (y'know, like you get in the real world). The intention being to give you streams whenever it can get them. It does _not_ require gdb to be running. For the time being traceswo is not turned on by default in the BMP to avoid possible interactions and making the overall thing less reliable so You do need gdb to send the initial 'monitor traceswo' to the probe, but beyond that there's no requirement for gdb to be present. Reliability =========== A whole chunk of work has gone into making sure the dataflow over the SWO link is reliable. The TL;DR is that the link _is_ reliable. There are factors outside of our control (i.e. the USB bus you connect to) that could potentially break the reliabilty but there's not too much we can do about that since the SWO link is unidirectional (no opportunity for re-transmits). The following section provides evidence for the claim that the link is good; A test 'mule' sends data flat out to the link at the maximum data rate of 2.25Mbps using a loop like the one below; while (1) { for (uint32_t r=0; r<26; r++) { for (uint32_t g=0; g<31; g++) { ITM_SendChar('A'+r); } ITM_SendChar('\n'); } } 100MB of data (more than 200MB of actual SWO packets, due to the encoding) was sent from the mule to the BMP where the output from swolisten chan00 was cat'ted into a file; >cat swo/chan00 > o ....this process was interrupted once the file had grown to 100MB. The first and last lines were removed from it (these represent previously buffered data and an incomplete packet at the point where the capture was interrupted) and the resulting file analysed for consistency; > sort o | uniq -c The output was; 126462 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 126462 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 126462 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 126462 DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 126461 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 126461 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 126461 GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG 126461 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 126461 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 126461 JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ 126461 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 126461 LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL 126461 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 126461 NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN 126461 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO 126461 PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP 126461 QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ 126461 RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR 126461 SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 126461 TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 126461 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU 126461 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV 126461 WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW 126461 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 126461 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY 126461 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ (On inspection, the last line of recorded data was indeed a 'D' line). Swolisten, using a TTL Serial Dongle ==================================== The NRZ data that comes out of the SWO is just UART formatted, but in a frame. swolisten has been extended to accomodate TTL Serial Dongles that can pick this up. Success has been had with CP2102 dongles at up to 921600 baud. To use this mode just connect SWO to the RX pin of your dongle, and start swolisten with parmeters representing the speed and port. An example; >./swolisten -p /dev/cu.SLAB_USBtoUART -v -b swo/ -s 921600 Any individual dongle will only support certain baudrates (Generally multiples of 115200) so you may have to experiment to find the best supported ones. For the CP2102 dongle 1.3824Mbps wasn't supported and 1.8432Mbps returned corrupted data. Please email dave@marples.net with information about dongles you find work well and at what speed. Further information =================== SWO is a wide field. Read e.g. the blogs around SWD on http://shadetail.com/blog/swo-starting-the-steroids/ An open source program suite for SWO under active development is https://github.com/mubes/orbuculum