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