1 /*********************************************************************
2 *                    SEGGER Microcontroller GmbH                     *
3 *                        The Embedded Experts                        *
4 **********************************************************************
5 *                                                                    *
6 *            (c) 1995 - 2024 SEGGER Microcontroller GmbH             *
7 *                                                                    *
8 *       www.segger.com     Support: support@segger.com               *
9 *                                                                    *
10 **********************************************************************
11 *                                                                    *
12 *       SEGGER SystemView * Real-time application analysis           *
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 SystemView and 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 *       SystemView version: 3.58                                    *
46 *                                                                    *
47 **********************************************************************
48 ---------------------------END-OF-HEADER------------------------------
49 File    : RTT_Syscalls_KEIL.c
50 Purpose : Retargeting module for KEIL MDK-CM3.
51           Low-level functions for using printf() via RTT
52 Revision: $Rev: 29653 $
53 Notes   : (1) https://wiki.segger.com/Keil_MDK-ARM#RTT_in_uVision
54 ----------------------------------------------------------------------
55 */
56 #if (defined __CC_ARM) || (defined __ARMCC_VERSION)
57 
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <rt_sys.h>
62 #include <rt_misc.h>
63 
64 #include "SEGGER_RTT.h"
65 /*********************************************************************
66 *
67 *       #pragmas
68 *
69 **********************************************************************
70 */
71 #if __ARMCC_VERSION < 6000000
72 #pragma import(__use_no_semihosting)
73 #endif
74 
75 #ifdef _MICROLIB
76   #pragma import(__use_full_stdio)
77 #endif
78 
79 /*********************************************************************
80 *
81 *       Defines non-configurable
82 *
83 **********************************************************************
84 */
85 
86 /* Standard IO device handles - arbitrary, but any real file system handles must be
87    less than 0x8000. */
88 #define STDIN             0x8001    // Standard Input Stream
89 #define STDOUT            0x8002    // Standard Output Stream
90 #define STDERR            0x8003    // Standard Error Stream
91 
92 /*********************************************************************
93 *
94 *       Public const
95 *
96 **********************************************************************
97 */
98 #if __ARMCC_VERSION < 5000000
99 //const char __stdin_name[]  = "STDIN";
100 const char __stdout_name[] = "STDOUT";
101 const char __stderr_name[] = "STDERR";
102 #endif
103 
104 /*********************************************************************
105 *
106 *       Public code
107 *
108 **********************************************************************
109 */
110 
111 /*********************************************************************
112 *
113 *       _ttywrch
114 *
115 *  Function description:
116 *    Outputs a character to the console
117 *
118 *  Parameters:
119 *    c    - character to output
120 *
121 */
_ttywrch(int c)122 void _ttywrch(int c) {
123   fputc(c, stdout); // stdout
124   fflush(stdout);
125 }
126 
127 /*********************************************************************
128 *
129 *       _sys_open
130 *
131 *  Function description:
132 *    Opens the device/file in order to do read/write operations
133 *
134 *  Parameters:
135 *    sName        - sName of the device/file to open
136 *    OpenMode    - This parameter is currently ignored
137 *
138 *  Return value:
139 *    != 0     - Handle to the object to open, otherwise
140 *    == 0     -"device" is not handled by this module
141 *
142 */
_sys_open(const char * sName,int OpenMode)143 FILEHANDLE _sys_open(const char * sName, int OpenMode) {
144   (void)OpenMode;
145   // Register standard Input Output devices.
146   if (strcmp(sName, __stdout_name) == 0) {
147     return (STDOUT);
148   } else if (strcmp(sName, __stderr_name) == 0) {
149     return (STDERR);
150   } else
151   return (0);  // Not implemented
152 }
153 
154 /*********************************************************************
155 *
156 *       _sys_close
157 *
158 *  Function description:
159 *    Closes the handle to the open device/file
160 *
161 *  Parameters:
162 *    hFile    - Handle to a file opened via _sys_open
163 *
164 *  Return value:
165 *    0     - device/file closed
166 *
167 */
_sys_close(FILEHANDLE hFile)168 int _sys_close(FILEHANDLE hFile) {
169   (void)hFile;
170   return 0;  // Not implemented
171 }
172 
173 /*********************************************************************
174 *
175 *       _sys_write
176 *
177 *  Function description:
178 *    Writes the data to an open handle.
179 *    Currently this function only outputs data to the console
180 *
181 *  Parameters:
182 *    hFile    - Handle to a file opened via _sys_open
183 *    pBuffer  - Pointer to the data that shall be written
184 *    NumBytes      - Number of bytes to write
185 *    Mode     - The Mode that shall be used
186 *
187 *  Return value:
188 *    Number of bytes *not* written to the file/device
189 *
190 */
_sys_write(FILEHANDLE hFile,const unsigned char * pBuffer,unsigned NumBytes,int Mode)191 int _sys_write(FILEHANDLE hFile, const unsigned char * pBuffer, unsigned NumBytes, int Mode) {
192   int r = 0;
193 
194   (void)Mode;
195   if (hFile == STDOUT) {
196     SEGGER_RTT_Write(0, (const char*)pBuffer, NumBytes);
197 		return 0;
198   }
199   return r;
200 }
201 
202 /*********************************************************************
203 *
204 *       _sys_istty
205 *
206 *  Function description:
207 *    This function shall return whether the opened file
208 *    is a console device or not.
209 *
210 *  Parameters:
211 *    hFile    - Handle to a file opened via _sys_open
212 *
213 *  Return value:
214 *    1       - Device is     a console
215 *    0       - Device is not a console
216 *
217 */
_sys_istty(FILEHANDLE hFile)218 int _sys_istty(FILEHANDLE hFile) {
219   if (hFile > 0x8000) {
220     return (1);
221   }
222   return (0);  // Not implemented
223 }
224 
225 /*********************************************************************
226 *
227 *       _sys_seek
228 *
229 *  Function description:
230 *    Seeks via the file to a specific position
231 *
232 *  Parameters:
233 *    hFile  - Handle to a file opened via _sys_open
234 *    Pos    -
235 *
236 *  Return value:
237 *    int       -
238 *
239 */
_sys_seek(FILEHANDLE hFile,long Pos)240 int _sys_seek(FILEHANDLE hFile, long Pos) {
241   (void)hFile;
242   (void)Pos;
243   return (0);  // Not implemented
244 }
245 
246 /*********************************************************************
247 *
248 *       _sys_flen
249 *
250 *  Function description:
251 *    Returns the length of the opened file handle
252 *
253 *  Parameters:
254 *    hFile    - Handle to a file opened via _sys_open
255 *
256 *  Return value:
257 *    Length of the file
258 *
259 */
_sys_flen(FILEHANDLE hFile)260 long _sys_flen(FILEHANDLE hFile) {
261   (void)hFile;
262   return (0);  // Not implemented
263 }
264 
265 #if (__ARMCC_VERSION <= 6000000) // The following functions are not required to be implemented for CC version > 6.
266 /*********************************************************************
267 *
268 *       _sys_read
269 *
270 *  Function description:
271 *    Reads data from an open handle.
272 *    Currently this modules does nothing.
273 *
274 *  Parameters:
275 *    hFile    - Handle to a file opened via _sys_open
276 *    pBuffer  - Pointer to buffer to store the read data
277 *    NumBytes      - Number of bytes to read
278 *    Mode     - The Mode that shall be used
279 *
280 *  Return value:
281 *    Number of bytes read from the file/device
282 *
283 */
_sys_read(FILEHANDLE hFile,unsigned char * pBuffer,unsigned NumBytes,int Mode)284 int _sys_read(FILEHANDLE hFile, unsigned char * pBuffer, unsigned NumBytes, int Mode) {
285   (void)hFile;
286   (void)pBuffer;
287   (void)NumBytes;
288   (void)Mode;
289   return (0);  // Not implemented
290 }
291 
292 /*********************************************************************
293 *
294 *       _sys_ensure
295 *
296 *  Function description:
297 *
298 *
299 *  Parameters:
300 *    hFile    - Handle to a file opened via _sys_open
301 *
302 *  Return value:
303 *    int       -
304 *
305 */
_sys_ensure(FILEHANDLE hFile)306 int _sys_ensure(FILEHANDLE hFile) {
307   (void)hFile;
308   return (-1);  // Not implemented
309 }
310 
311 /*********************************************************************
312 *
313 *       _sys_tmpnam
314 *
315 *  Function description:
316 *    This function converts the file number fileno for a temporary
317 *    file to a unique filename, for example, tmp0001.
318 *
319 *  Parameters:
320 *    pBuffer    - Pointer to a buffer to store the name
321 *    FileNum    - file number to convert
322 *    MaxLen     - Size of the buffer
323 *
324 *  Return value:
325 *     1 - Error
326 *     0 - Success
327 *
328 */
329 #if __ARMCC_VERSION >= 6190000
_sys_tmpnam(char * pBuffer,int FileNum,unsigned MaxLen)330 void _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) {
331   (void)pBuffer;
332   (void)FileNum;
333   (void)MaxLen;
334   return;      // Not implemented
335 }
336 #else
_sys_tmpnam(char * pBuffer,int FileNum,unsigned MaxLen)337 int _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) {
338   (void)pBuffer;
339   (void)FileNum;
340   (void)MaxLen;
341   return (1);  // Not implemented
342 }
343 #endif
344 
345 /*********************************************************************
346 *
347 *       _sys_command_string
348 *
349 *  Function description:
350 *    This function shall execute a system command.
351 *
352 *  Parameters:
353 *    cmd    - Pointer to the command string
354 *    len    - Length of the string
355 *
356 *  Return value:
357 *    == NULL - Command was not successfully executed
358 *    == sCmd - Command was passed successfully
359 *
360 */
_sys_command_string(char * cmd,int len)361 char * _sys_command_string(char * cmd, int len) {
362   (void)len;
363   return cmd;  // Not implemented
364 }
365 
366 /*********************************************************************
367 *
368 *       _sys_exit
369 *
370 *  Function description:
371 *    This function is called when the application returns from main
372 *
373 *  Parameters:
374 *    ReturnCode    - Return code from the main function
375 *
376 *
377 */
_sys_exit(int ReturnCode)378 void _sys_exit(int ReturnCode) {
379   (void)ReturnCode;
380   while (1);  // Not implemented
381 }
382 
383 #if __ARMCC_VERSION >= 5000000
384 /*********************************************************************
385 *
386 *       stdout_putchar
387 *
388 *  Function description:
389 *    Put a character to the stdout
390 *
391 *  Parameters:
392 *    ch    - Character to output
393 *
394 *
395 */
stdout_putchar(int ch)396 int stdout_putchar(int ch) {
397   (void)ch;
398   return ch;  // Not implemented
399 }
400 #endif
401 
402 #endif // #if __ARMCC_VERSION <= 6000000
403 #endif // #if (defined __CC_ARM) || (defined __ARMCC_VERSION)
404 /*************************** End of file ****************************/
405