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 mbed_nucleo_swo DISCO-F429ZI_LCDTS_demo_richard TEST_SM_SPEED

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