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