Serial Wire Output (SWO) viewer for tracing purposes. Tested on F401 and ST-LINK Utility as well as for F103 and Segger J-Link SWO viewer.

Dependents:   WiFi_Scanner DISCO-F429ZI_LCDTS_demo_richard mbed_nucleo_swo

Committer:
wim
Date:
Thu Aug 24 18:15:02 2017 +0000
Revision:
4:53de8ef789f3
Parent:
3:e5af2e131b95
Added stream claim for stdout, proposed by Pavel Sorejs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim1:bae4cff278f6 1/* mbed SWO Library
wim1:bae4cff278f6 2 * Copyright (c) 2014, v01: WH. Ported from Segger example
wim3:e5af2e131b95 3 * v02: WH. Added Class with Stream support
wim4:53de8ef789f3 4 * 2017, v03: WH,PS. Added stream claim for stdout, proposed by Pavel Sorejs
wim1:bae4cff278f6 5 *
wim2:ef928f61a770 6 * Simple implementation for tracing via Serial Wire Output(SWO) for Cortex-M processors.
wim1:bae4cff278f6 7 * It can be used with Host PC software such as ST-LINK Utility or Segger J-Link SWO viewer.
wim1:bae4cff278f6 8 * This sample implementation ensures that output via SWO is enabled in order to guarantee
wim1:bae4cff278f6 9 * that the application does not hang.
wim1:bae4cff278f6 10 *
wim1:bae4cff278f6 11 * Permission is hereby granted, free of charge, to any person obtaining a copy
wim1:bae4cff278f6 12 * of this software and associated documentation files (the "Software"), to deal
wim1:bae4cff278f6 13 * in the Software without restriction, including without limitation the rights
wim1:bae4cff278f6 14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim1:bae4cff278f6 15 * copies of the Software, and to permit persons to whom the Software is
wim1:bae4cff278f6 16 * furnished to do so, subject to the following conditions:
wim1:bae4cff278f6 17 *
wim1:bae4cff278f6 18 * The above copyright notice and this permission notice shall be included in
wim1:bae4cff278f6 19 * all copies or substantial portions of the Software.
wim1:bae4cff278f6 20 *
wim1:bae4cff278f6 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim1:bae4cff278f6 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim1:bae4cff278f6 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim1:bae4cff278f6 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim1:bae4cff278f6 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim1:bae4cff278f6 26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim1:bae4cff278f6 27 * THE SOFTWARE.
wim1:bae4cff278f6 28 */
wim1:bae4cff278f6 29
wim1:bae4cff278f6 30#ifndef MBED_SWO_H
wim1:bae4cff278f6 31#define MBED_SWO_H
wim0:0fd55660fc26 32
wim3:e5af2e131b95 33//
wim3:e5af2e131b95 34// This is the Class implementation
wim3:e5af2e131b95 35//
wim3:e5af2e131b95 36
wim3:e5af2e131b95 37/**
wim3:e5af2e131b95 38 * @code
wim3:e5af2e131b95 39 * #include "mbed.h"
wim3:e5af2e131b95 40 * #include "SWO.h"
wim3:e5af2e131b95 41 *
wim3:e5af2e131b95 42 * DigitalOut myled(LED1);
wim3:e5af2e131b95 43 *
wim3:e5af2e131b95 44 * Serial pc(SERIAL_TX, SERIAL_RX);
wim3:e5af2e131b95 45 *
wim3:e5af2e131b95 46 * SWO_Channel SWO();
wim3:e5af2e131b95 47 *
wim3:e5af2e131b95 48 * int main() {
wim3:e5af2e131b95 49 * pc.printf("Hello World\n\r");
wim3:e5af2e131b95 50 *
wim3:e5af2e131b95 51 * SWO.printf("\r\nHello World from SWO\r\n");
wim3:e5af2e131b95 52 * SWO.printf("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);
wim3:e5af2e131b95 53 *
wim3:e5af2e131b95 54 * while(1) {
wim3:e5af2e131b95 55 * myled = 1; // LED is ON
wim3:e5af2e131b95 56 * wait(0.2); // 200 ms
wim3:e5af2e131b95 57 * myled = 0; // LED is OFF
wim3:e5af2e131b95 58 * wait(1.0); // 1 sec
wim3:e5af2e131b95 59 *
wim3:e5af2e131b95 60 * SWO.putc('#');
wim3:e5af2e131b95 61 * }
wim3:e5af2e131b95 62 * }
wim3:e5af2e131b95 63 * @endcode
wim3:e5af2e131b95 64 */
wim3:e5af2e131b95 65
wim3:e5af2e131b95 66/** An SWO interface for debugging that supports Stream
wim3:e5af2e131b95 67 *
wim3:e5af2e131b95 68 * @brief Currently works on nucleo ST-LINK using ST-Link Utility and other devices that support SWD/SWO using Segger SWO viewer
wim3:e5af2e131b95 69 *
wim3:e5af2e131b95 70 */
wim3:e5af2e131b95 71class SWO_Channel : public Stream {
wim3:e5af2e131b95 72
wim3:e5af2e131b95 73public:
wim3:e5af2e131b95 74 /** Create an SWO interface for debugging that supports Stream
wim3:e5af2e131b95 75 *
wim4:53de8ef789f3 76 * @param const char *name Channel name (default = none)
wim3:e5af2e131b95 77 */
wim4:53de8ef789f3 78 SWO_Channel(const char *name=NULL);
wim3:e5af2e131b95 79
wim4:53de8ef789f3 80 /**
wim4:53de8ef789f3 81 * Function: claim
wim4:53de8ef789f3 82 *
wim4:53de8ef789f3 83 * Redirect a stream to this SWO object
wim4:53de8ef789f3 84 *
wim4:53de8ef789f3 85 * Important: A name parameter must have been added when creating the SWO object:
wim4:53de8ef789f3 86 *
wim4:53de8ef789f3 87 * @code
wim4:53de8ef789f3 88 * #include "SWO.h"
wim4:53de8ef789f3 89 * ...
wim4:53de8ef789f3 90 * SWO_Channel pc("modser");
wim4:53de8ef789f3 91 *
wim4:53de8ef789f3 92 * int main() {
wim4:53de8ef789f3 93 * pc.claim(); // capture <stdout>
wim4:53de8ef789f3 94 * pc.printf("Uses the SWO library\r\n");
wim4:53de8ef789f3 95 * printf("So does this!\r\n");
wim4:53de8ef789f3 96 * }
wim4:53de8ef789f3 97 * @endcode
wim4:53de8ef789f3 98 *
wim4:53de8ef789f3 99 * @ingroup API
wim4:53de8ef789f3 100 * @param FILE *stream The stream to redirect (default = stdout)
wim4:53de8ef789f3 101 * @return true if succeeded, else false
wim4:53de8ef789f3 102 */
wim4:53de8ef789f3 103 bool claim(FILE *stream = stdout);
wim4:53de8ef789f3 104
wim3:e5af2e131b95 105#if DOXYGEN_ONLY
wim3:e5af2e131b95 106 /** Write a character to the display
wim3:e5af2e131b95 107 *
wim3:e5af2e131b95 108 * @param c The character to write to the display
wim3:e5af2e131b95 109 */
wim3:e5af2e131b95 110 int putc(int c);
wim3:e5af2e131b95 111
wim3:e5af2e131b95 112 /** Write a formatted string to the display
wim3:e5af2e131b95 113 *
wim3:e5af2e131b95 114 * @param format A printf-style format string, followed by the
wim3:e5af2e131b95 115 * variables to use in formatting the string.
wim3:e5af2e131b95 116 */
wim3:e5af2e131b95 117 int printf(const char* format, ...);
wim3:e5af2e131b95 118#endif
wim3:e5af2e131b95 119
wim3:e5af2e131b95 120protected:
wim3:e5af2e131b95 121 // Stream implementation functions
wim3:e5af2e131b95 122 virtual int _putc(int value);
wim3:e5af2e131b95 123 virtual int _getc();
wim3:e5af2e131b95 124
wim3:e5af2e131b95 125private:
wim3:e5af2e131b95 126
wim3:e5af2e131b95 127};
wim3:e5af2e131b95 128
wim3:e5af2e131b95 129
wim3:e5af2e131b95 130//
wim3:e5af2e131b95 131//This is the classic implementation
wim3:e5af2e131b95 132//
wim3:e5af2e131b95 133
wim1:bae4cff278f6 134/**
wim1:bae4cff278f6 135 * @code
wim1:bae4cff278f6 136 * #include "mbed.h"
wim1:bae4cff278f6 137 * #include "SWO.h"
wim1:bae4cff278f6 138 *
wim1:bae4cff278f6 139 * DigitalOut myled(LED1);
wim1:bae4cff278f6 140 *
wim1:bae4cff278f6 141 * Serial pc(SERIAL_TX, SERIAL_RX);
wim1:bae4cff278f6 142 *
wim1:bae4cff278f6 143 * int main() {
wim1:bae4cff278f6 144 * pc.printf("Hello World\n\r");
wim1:bae4cff278f6 145 *
wim1:bae4cff278f6 146 * SWO_PrintString("\r\nHello World from SWO\r\n");
wim1:bae4cff278f6 147 * char message[64];
wim1:bae4cff278f6 148 * sprintf(message, "CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);
wim1:bae4cff278f6 149 * SWO_PrintString(message);
wim1:bae4cff278f6 150 *
wim1:bae4cff278f6 151 * while(1) {
wim1:bae4cff278f6 152 * myled = 1; // LED is ON
wim1:bae4cff278f6 153 * wait(0.2); // 200 ms
wim1:bae4cff278f6 154 * myled = 0; // LED is OFF
wim1:bae4cff278f6 155 * wait(1.0); // 1 sec
wim1:bae4cff278f6 156 *
wim1:bae4cff278f6 157 * SWO_PrintString("#");
wim1:bae4cff278f6 158 * }
wim1:bae4cff278f6 159 * }
wim1:bae4cff278f6 160 * @endcode
wim1:bae4cff278f6 161 */
wim1:bae4cff278f6 162
wim1:bae4cff278f6 163// Prototypes
wim1:bae4cff278f6 164
wim1:bae4cff278f6 165/**
wim1:bae4cff278f6 166* @brief
wim1:bae4cff278f6 167* Checks if SWO is set up. If it is not, return,
wim1:bae4cff278f6 168* to avoid program hangs if no debugger is connected.
wim1:bae4cff278f6 169* If it is set up, print a character to the ITM_STIM register
wim1:bae4cff278f6 170* in order to provide data for SWO.
wim1:bae4cff278f6 171* @param c The Character to be printed.
wim1:bae4cff278f6 172* @notes Additional checks for device specific registers can be added.
wim0:0fd55660fc26 173*/
wim0:0fd55660fc26 174void SWO_PrintChar (char c);
wim1:bae4cff278f6 175
wim1:bae4cff278f6 176
wim1:bae4cff278f6 177/**
wim1:bae4cff278f6 178*
wim1:bae4cff278f6 179* SWO_PrintString()
wim1:bae4cff278f6 180*
wim1:bae4cff278f6 181* @brief Print a string via SWO.
wim1:bae4cff278f6 182* @param *s The string to be printed.
wim1:bae4cff278f6 183*/
wim0:0fd55660fc26 184void SWO_PrintString(const char *s);
wim0:0fd55660fc26 185
wim0:0fd55660fc26 186#endif