1 /********************************************************************* 2 * SEGGER Microcontroller GmbH * 3 * The Embedded Experts * 4 ********************************************************************** 5 * * 6 * (c) 1995 - 2019 SEGGER Microcontroller GmbH * 7 * * 8 * www.segger.com Support: [email protected] * 9 * * 10 ********************************************************************** 11 * * 12 * SEGGER RTT * Real Time Transfer for embedded targets * 13 * * 14 ********************************************************************** 15 * * 16 * All rights reserved. * 17 * * 18 * SEGGER strongly recommends to not make any changes * 19 * to or modify the source code of this software in order to stay * 20 * compatible with the RTT protocol and J-Link. * 21 * * 22 * Redistribution and use in source and binary forms, with or * 23 * without modification, are permitted provided that the following * 24 * condition is met: * 25 * * 26 * o Redistributions of source code must retain the above copyright * 27 * notice, this condition and the following disclaimer. * 28 * * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * 30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * 32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * 33 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * 34 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * 35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * 36 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * 37 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 38 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * 40 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 41 * DAMAGE. * 42 * * 43 ********************************************************************** 44 ---------------------------END-OF-HEADER------------------------------ 45 File : SEGGER_RTT_Syscalls_SES.c 46 Purpose : Reimplementation of printf, puts and __getchar using RTT 47 in SEGGER Embedded Studio. 48 To use RTT for printf output, include this file in your 49 application. 50 Revision: $Rev: 24316 $ 51 ---------------------------------------------------------------------- 52 */ 53 #if (defined __SES_ARM) || (defined __SES_RISCV) || (defined __CROSSWORKS_ARM) 54 55 #include "SEGGER_RTT.h" 56 #include <stdarg.h> 57 #include <stdio.h> 58 #include "limits.h" 59 #include "__libc.h" 60 #include "__vfprintf.h" 61 62 /********************************************************************* 63 * 64 * Defines, configurable 65 * 66 ********************************************************************** 67 */ 68 // 69 // Select string formatting implementation. 70 // 71 // RTT printf formatting 72 // - Configurable stack usage. (SEGGER_RTT_PRINTF_BUFFER_SIZE in SEGGER_RTT_Conf.h) 73 // - No maximum string length. 74 // - Limited conversion specifiers and flags. (See SEGGER_RTT_printf.c) 75 // Standard library printf formatting 76 // - Configurable formatting capabilities. 77 // - Full conversion specifier and flag support. 78 // - Maximum string length has to be known or (slightly) slower character-wise output. 79 // 80 // #define PRINTF_USE_SEGGER_RTT_FORMATTING 0 // Use standard library formatting 81 // #define PRINTF_USE_SEGGER_RTT_FORMATTING 1 // Use RTT formatting 82 // 83 #ifndef PRINTF_USE_SEGGER_RTT_FORMATTING 84 #define PRINTF_USE_SEGGER_RTT_FORMATTING 0 85 #endif 86 // 87 // If using standard library formatting, 88 // select maximum output string buffer size or character-wise output. 89 // 90 // #define PRINTF_BUFFER_SIZE 0 // Use character-wise output 91 // #define PRINTF_BUFFER_SIZE 128 // Default maximum string length 92 // 93 #ifndef PRINTF_BUFFER_SIZE 94 #define PRINTF_BUFFER_SIZE 128 95 #endif 96 97 #if PRINTF_USE_SEGGER_RTT_FORMATTING // Use SEGGER RTT formatting implementation 98 /********************************************************************* 99 * 100 * Function prototypes 101 * 102 ********************************************************************** 103 */ 104 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); 105 106 /********************************************************************* 107 * 108 * Global functions, printf 109 * 110 ********************************************************************** 111 */ 112 /********************************************************************* 113 * 114 * printf() 115 * 116 * Function description 117 * print a formatted string using RTT and SEGGER RTT formatting. 118 */ 119 int printf(const char *fmt,...) { 120 int n; 121 va_list args; 122 123 va_start (args, fmt); 124 n = SEGGER_RTT_vprintf(0, fmt, &args); 125 va_end(args); 126 return n; 127 } 128 129 #elif PRINTF_BUFFER_SIZE == 0 // Use standard library formatting with character-wise output 130 131 /********************************************************************* 132 * 133 * Static functions 134 * 135 ********************************************************************** 136 */ 137 static int _putchar(int x, __printf_tag_ptr ctx) { 138 (void)ctx; 139 SEGGER_RTT_Write(0, (char *)&x, 1); 140 return x; 141 } 142 143 /********************************************************************* 144 * 145 * Global functions, printf 146 * 147 ********************************************************************** 148 */ 149 /********************************************************************* 150 * 151 * printf() 152 * 153 * Function description 154 * print a formatted string character-wise, using RTT and standard 155 * library formatting. 156 */ 157 int printf(const char *fmt, ...) { 158 int n; 159 va_list args; 160 __printf_t iod; 161 162 va_start(args, fmt); 163 iod.string = 0; 164 iod.maxchars = INT_MAX; 165 iod.output_fn = _putchar; 166 SEGGER_RTT_LOCK(); 167 n = __vfprintf(&iod, fmt, args); 168 SEGGER_RTT_UNLOCK(); 169 va_end(args); 170 return n; 171 } 172 173 #else // Use standard library formatting with static buffer 174 175 /********************************************************************* 176 * 177 * Global functions, printf 178 * 179 ********************************************************************** 180 */ 181 /********************************************************************* 182 * 183 * printf() 184 * 185 * Function description 186 * print a formatted string using RTT and standard library formatting. 187 */ 188 int printf(const char *fmt,...) { 189 int n; 190 char aBuffer[PRINTF_BUFFER_SIZE]; 191 va_list args; 192 193 va_start (args, fmt); 194 n = vsnprintf(aBuffer, sizeof(aBuffer), fmt, args); 195 if (n > (int)sizeof(aBuffer)) { 196 SEGGER_RTT_Write(0, aBuffer, sizeof(aBuffer)); 197 } else if (n > 0) { 198 SEGGER_RTT_Write(0, aBuffer, n); 199 } 200 va_end(args); 201 return n; 202 } 203 #endif 204 205 /********************************************************************* 206 * 207 * Global functions 208 * 209 ********************************************************************** 210 */ 211 /********************************************************************* 212 * 213 * puts() 214 * 215 * Function description 216 * print a string using RTT. 217 */ 218 int puts(const char *s) { 219 return SEGGER_RTT_WriteString(0, s); 220 } 221 222 /********************************************************************* 223 * 224 * __putchar() 225 * 226 * Function description 227 * Write one character via RTT. 228 */ 229 int __putchar(int x, __printf_tag_ptr ctx) { 230 (void)ctx; 231 SEGGER_RTT_Write(0, (char *)&x, 1); 232 return x; 233 } 234 235 /********************************************************************* 236 * 237 * __getchar() 238 * 239 * Function description 240 * Wait for and get a character via RTT. 241 */ 242 int __getchar() { 243 return SEGGER_RTT_WaitKey(); 244 } 245 246 #endif 247 /****** End Of File *************************************************/ 248