1 /*********************************************************************
2 * SEGGER Microcontroller GmbH *
3 * The Embedded Experts *
4 **********************************************************************
5 * *
6 * (c) 1995 - 2021 SEGGER Microcontroller GmbH *
7 * *
8 * www.segger.com Support: support@segger.com *
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 * *
45 * RTT version: 7.22 *
46 * *
47 **********************************************************************
48
49 ---------------------------END-OF-HEADER------------------------------
50 File : SEGGER_RTT_Syscalls_SES.c
51 Purpose : Reimplementation of printf, puts and __getchar using RTT
52 in SEGGER Embedded Studio.
53 To use RTT for printf output, include this file in your
54 application.
55 Revision: $Rev: 18539 $
56 ----------------------------------------------------------------------
57 */
58 #if (defined __SES_ARM) || (defined __SES_RISCV) || (defined __CROSSWORKS_ARM)
59
60 #include "SEGGER_RTT.h"
61 #include <stdarg.h>
62 #include <stdio.h>
63 #include "limits.h"
64 #include "__libc.h"
65 #include "__vfprintf.h"
66
67 /*********************************************************************
68 *
69 * Defines, configurable
70 *
71 **********************************************************************
72 */
73 //
74 // Select string formatting implementation.
75 //
76 // RTT printf formatting
77 // - Configurable stack usage. (SEGGER_RTT_PRINTF_BUFFER_SIZE in SEGGER_RTT_Conf.h)
78 // - No maximum string length.
79 // - Limited conversion specifiers and flags. (See SEGGER_RTT_printf.c)
80 // Standard library printf formatting
81 // - Configurable formatting capabilities.
82 // - Full conversion specifier and flag support.
83 // - Maximum string length has to be known or (slightly) slower character-wise output.
84 //
85 // #define PRINTF_USE_SEGGER_RTT_FORMATTING 0 // Use standard library formatting
86 // #define PRINTF_USE_SEGGER_RTT_FORMATTING 1 // Use RTT formatting
87 //
88 #ifndef PRINTF_USE_SEGGER_RTT_FORMATTING
89 #define PRINTF_USE_SEGGER_RTT_FORMATTING 0
90 #endif
91 //
92 // If using standard library formatting,
93 // select maximum output string buffer size or character-wise output.
94 //
95 // #define PRINTF_BUFFER_SIZE 0 // Use character-wise output
96 // #define PRINTF_BUFFER_SIZE 128 // Default maximum string length
97 //
98 #ifndef PRINTF_BUFFER_SIZE
99 #define PRINTF_BUFFER_SIZE 128
100 #endif
101
102 #if PRINTF_USE_SEGGER_RTT_FORMATTING // Use SEGGER RTT formatting implementation
103 /*********************************************************************
104 *
105 * Function prototypes
106 *
107 **********************************************************************
108 */
109 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char *sFormat, va_list *pParamList);
110
111 /*********************************************************************
112 *
113 * Global functions, printf
114 *
115 **********************************************************************
116 */
117 /*********************************************************************
118 *
119 * printf()
120 *
121 * Function description
122 * print a formatted string using RTT and SEGGER RTT formatting.
123 */
printf(const char * fmt,...)124 int printf(const char *fmt, ...)
125 {
126 int n;
127 va_list args;
128
129 va_start(args, fmt);
130 n = SEGGER_RTT_vprintf(0, fmt, &args);
131 va_end(args);
132 return n;
133 }
134
135 #elif PRINTF_BUFFER_SIZE == 0 // Use standard library formatting with character-wise output
136
137 /*********************************************************************
138 *
139 * Static functions
140 *
141 **********************************************************************
142 */
_putchar(int x,__printf_tag_ptr ctx)143 static int _putchar(int x, __printf_tag_ptr ctx)
144 {
145 (void)ctx;
146 SEGGER_RTT_Write(0, (char *)&x, 1);
147 return x;
148 }
149
150 /*********************************************************************
151 *
152 * Global functions, printf
153 *
154 **********************************************************************
155 */
156 /*********************************************************************
157 *
158 * printf()
159 *
160 * Function description
161 * print a formatted string character-wise, using RTT and standard
162 * library formatting.
163 */
printf(const char * fmt,...)164 int printf(const char *fmt, ...)
165 {
166 int n;
167 va_list args;
168 __printf_t iod;
169
170 va_start(args, fmt);
171 iod.string = 0;
172 iod.maxchars = INT_MAX;
173 iod.output_fn = _putchar;
174 SEGGER_RTT_LOCK();
175 n = __vfprintf(&iod, fmt, args);
176 SEGGER_RTT_UNLOCK();
177 va_end(args);
178 return n;
179 }
180
181 #else // Use standard library formatting with static buffer
182
183 /*********************************************************************
184 *
185 * Global functions, printf
186 *
187 **********************************************************************
188 */
189 /*********************************************************************
190 *
191 * printf()
192 *
193 * Function description
194 * print a formatted string using RTT and standard library formatting.
195 */
printf(const char * fmt,...)196 int printf(const char *fmt, ...)
197 {
198 int n;
199 char aBuffer[PRINTF_BUFFER_SIZE];
200 va_list args;
201
202 va_start(args, fmt);
203 n = vsnprintf(aBuffer, sizeof(aBuffer), fmt, args);
204 if (n > (int)sizeof(aBuffer))
205 {
206 SEGGER_RTT_Write(0, aBuffer, sizeof(aBuffer));
207 }
208 else if (n > 0)
209 {
210 SEGGER_RTT_Write(0, aBuffer, n);
211 }
212 va_end(args);
213 return n;
214 }
215 #endif
216
217 /*********************************************************************
218 *
219 * Global functions
220 *
221 **********************************************************************
222 */
223 /*********************************************************************
224 *
225 * puts()
226 *
227 * Function description
228 * print a string using RTT.
229 */
puts(const char * s)230 int puts(const char *s)
231 {
232 return SEGGER_RTT_WriteString(0, s);
233 }
234
235 /*********************************************************************
236 *
237 * __putchar()
238 *
239 * Function description
240 * Write one character via RTT.
241 */
__putchar(int x,__printf_tag_ptr ctx)242 int __putchar(int x, __printf_tag_ptr ctx)
243 {
244 (void)ctx;
245 SEGGER_RTT_Write(0, (char *)&x, 1);
246 return x;
247 }
248
249 /*********************************************************************
250 *
251 * __getchar()
252 *
253 * Function description
254 * Wait for and get a character via RTT.
255 */
__getchar()256 int __getchar()
257 {
258 return SEGGER_RTT_WaitKey();
259 }
260
261 #endif
262 /****** End Of File *************************************************/
263