1 /*
2  * Copyright 2017-2018, 2020, 2022NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  */
9 
10 #include <stdarg.h>
11 #include <stdlib.h>
12 #if defined(__CC_ARM) || defined(__ARMCC_VERSION)
13 #include <stdio.h>
14 #endif
15 #include <math.h>
16 #include "fsl_debug_console.h"
17 #include "fsl_adapter_uart.h"
18 #include "fsl_str.h"
19 
20 /*! @brief Keil: suppress ellipsis warning in va_arg usage below. */
21 #if defined(__CC_ARM)
22 #pragma diag_suppress 1256
23 #endif /* __CC_ARM */
24 
25 /*******************************************************************************
26  * Definitions
27  ******************************************************************************/
28 
29 /*! @brief This definition is maximum line that debugconsole can scanf each time.*/
30 #define IO_MAXLINE 20U
31 
32 /*! @brief The overflow value.*/
33 #ifndef HUGE_VAL
34 #define HUGE_VAL (99.e99)
35 #endif /* HUGE_VAL */
36 
37 /*! @brief State structure storing debug console. */
38 typedef struct DebugConsoleState
39 {
40     uint8_t uartHandleBuffer[HAL_UART_HANDLE_SIZE];
41     hal_uart_status_t (*putChar)(hal_uart_handle_t handle,
42                                  const uint8_t *data,
43                                  size_t length); /*!< put char function pointer */
44     hal_uart_status_t (*getChar)(hal_uart_handle_t handle,
45                                  uint8_t *data,
46                                  size_t length); /*!< get char function pointer */
47     serial_port_type_t serial_port_type;         /*!< The initialized port of the debug console. */
48 } debug_console_state_t;
49 
50 /*! @brief Type of KSDK printf function pointer. */
51 typedef int (*PUTCHAR_FUNC)(int a);
52 
53 /*******************************************************************************
54  * Variables
55  ******************************************************************************/
56 #if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART))
57 /*! @brief Debug UART state information. */
58 static debug_console_state_t s_debugConsole;
59 #endif
60 
61 /*******************************************************************************
62  * Prototypes
63  ******************************************************************************/
64 #if (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK))
65 static int DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr, const char *fmt, va_list ap);
66 #endif /* SDK_DEBUGCONSOLE */
67 
68 /*******************************************************************************
69  * Code
70  ******************************************************************************/
71 
72 /*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/
73 
74 #if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART))
75 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Init(uint8_t instance,uint32_t baudRate,serial_port_type_t device,uint32_t clkSrcFreq)76 status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq)
77 {
78     hal_uart_config_t usrtConfig;
79 
80     if (kSerialPort_Uart != device)
81     {
82         return kStatus_Fail;
83     }
84 
85     /* Set debug console to initialized to avoid duplicated initialized operation. */
86     s_debugConsole.serial_port_type = device;
87 
88     usrtConfig.srcClock_Hz  = clkSrcFreq;
89     usrtConfig.baudRate_Bps = baudRate;
90     usrtConfig.parityMode   = kHAL_UartParityDisabled;
91     usrtConfig.stopBitCount = kHAL_UartOneStopBit;
92     usrtConfig.enableRx     = 1U;
93     usrtConfig.enableTx     = 1U;
94     usrtConfig.enableRxRTS  = 0U;
95     usrtConfig.enableTxCTS  = 0U;
96     usrtConfig.instance     = instance;
97 #if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u))
98     usrtConfig.txFifoWatermark = 0U;
99     usrtConfig.rxFifoWatermark = 0U;
100 #endif
101     /* Enable clock and initial UART module follow user configure structure. */
102     (void)HAL_UartInit((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], &usrtConfig);
103     /* Set the function pointer for send and receive for this kind of device. */
104     s_debugConsole.putChar = HAL_UartSendBlocking;
105     s_debugConsole.getChar = HAL_UartReceiveBlocking;
106 
107     return kStatus_Success;
108 }
109 
110 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Deinit(void)111 status_t DbgConsole_Deinit(void)
112 {
113     if (kSerialPort_None == s_debugConsole.serial_port_type)
114     {
115         return kStatus_Success;
116     }
117 
118     (void)HAL_UartDeinit((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0]);
119 
120     s_debugConsole.serial_port_type = kSerialPort_None;
121     return kStatus_Success;
122 }
123 
124 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_EnterLowpower(void)125 status_t DbgConsole_EnterLowpower(void)
126 {
127     hal_uart_status_t DbgConsoleUartStatus = kStatus_HAL_UartError;
128     if (kSerialPort_Uart == s_debugConsole.serial_port_type)
129     {
130         DbgConsoleUartStatus = HAL_UartEnterLowpower((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0]);
131     }
132     return (status_t)DbgConsoleUartStatus;
133 }
134 
135 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_ExitLowpower(void)136 status_t DbgConsole_ExitLowpower(void)
137 {
138     hal_uart_status_t DbgConsoleUartStatus = kStatus_HAL_UartError;
139     if (kSerialPort_Uart == s_debugConsole.serial_port_type)
140     {
141         DbgConsoleUartStatus = HAL_UartExitLowpower((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0]);
142     }
143     return (status_t)DbgConsoleUartStatus;
144 }
145 
146 #endif /* DEBUGCONSOLE_REDIRECT_TO_SDK */
147 
148 #if (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK))
149 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Printf(const char * fmt_s,...)150 int DbgConsole_Printf(const char *fmt_s, ...)
151 {
152     va_list ap;
153     int result = 0;
154 
155     va_start(ap, fmt_s);
156     result = DbgConsole_Vprintf(fmt_s, ap);
157     va_end(ap);
158 
159     return result;
160 }
161 
162 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Vprintf(const char * fmt_s,va_list formatStringArg)163 int DbgConsole_Vprintf(const char *fmt_s, va_list formatStringArg)
164 {
165     int result = 0;
166 
167     /* Do nothing if the debug UART is not initialized. */
168     if (kSerialPort_None == s_debugConsole.serial_port_type)
169     {
170         return -1;
171     }
172 
173     result = DbgConsole_PrintfFormattedData(DbgConsole_Putchar, fmt_s, formatStringArg);
174 
175     return result;
176 }
177 
178 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Putchar(int dbgConsoleCh)179 int DbgConsole_Putchar(int dbgConsoleCh)
180 {
181     /* Do nothing if the debug UART is not initialized. */
182     if (kSerialPort_None == s_debugConsole.serial_port_type)
183     {
184         return -1;
185     }
186     (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&dbgConsoleCh), 1);
187 
188     return 1;
189 }
190 
191 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Scanf(char * fmt_s,...)192 int DbgConsole_Scanf(char *fmt_s, ...)
193 {
194     /* Plus one to store end of string char */
195     char temp_buf[IO_MAXLINE + 1];
196     va_list ap;
197     int32_t i;
198     char result;
199 
200     /* Do nothing if the debug UART is not initialized. */
201     if (kSerialPort_None == s_debugConsole.serial_port_type)
202     {
203         return -1;
204     }
205     va_start(ap, fmt_s);
206     temp_buf[0] = '\0';
207 
208     i = 0;
209     while (true)
210     {
211         if (i >= (int32_t)IO_MAXLINE)
212         {
213             break;
214         }
215 
216         result      = (char)DbgConsole_Getchar();
217         temp_buf[i] = result;
218 
219         if ((result == '\r') || (result == '\n'))
220         {
221             /* End of Line. */
222             if (i == 0)
223             {
224                 temp_buf[i] = '\0';
225                 i           = -1;
226             }
227             else
228             {
229                 break;
230             }
231         }
232 
233         i++;
234     }
235 
236     if (i == (int32_t)IO_MAXLINE)
237     {
238         temp_buf[i] = '\0';
239     }
240     else
241     {
242         temp_buf[i + 1] = '\0';
243     }
244     result = (char)StrFormatScanf(temp_buf, fmt_s, ap);
245     va_end(ap);
246 
247     return (int)result;
248 }
249 
250 /* See fsl_debug_console.h for documentation of this function. */
DbgConsole_Getchar(void)251 int DbgConsole_Getchar(void)
252 {
253     char dbgConsoleCh;
254     /* Do nothing if the debug UART is not initialized. */
255     if (kSerialPort_None == s_debugConsole.serial_port_type)
256     {
257         return -1;
258     }
259     while (kStatus_HAL_UartSuccess !=
260            s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&dbgConsoleCh), 1))
261     {
262         return -1;
263     }
264 
265     return (int)dbgConsoleCh;
266 }
267 
268 /*************Code for process formatted data*******************************/
269 /*!
270  * @brief This function puts padding character.
271  *
272  * @param[in] c         Padding character.
273  * @param[in] curlen    Length of current formatted string .
274  * @param[in] width     Width of expected formatted string.
275  * @param[in] count     Number of characters.
276  * @param[in] func_ptr  Function to put character out.
277  */
DbgConsole_PrintfPaddingCharacter(char c,int32_t curlen,int32_t width,int32_t * count,PUTCHAR_FUNC func_ptr)278 static void DbgConsole_PrintfPaddingCharacter(
279     char c, int32_t curlen, int32_t width, int32_t *count, PUTCHAR_FUNC func_ptr)
280 {
281     int32_t i;
282 
283     for (i = curlen; i < width; i++)
284     {
285         (void)func_ptr(c);
286         (*count)++;
287     }
288 }
289 
290 /*!
291  * @brief Converts a radix number to a string and return its length.
292  *
293  * @param[in] numstr    Converted string of the number.
294  * @param[in] nump      Pointer to the number.
295  * @param[in] neg       Polarity of the number.
296  * @param[in] radix     The radix to be converted to.
297  * @param[in] use_caps  Used to identify %x/X output format.
298 
299  * @return Length of the converted string.
300  */
DbgConsole_ConvertRadixNumToString(char * numstr,void * nump,int32_t neg,int32_t radix,bool use_caps)301 static int32_t DbgConsole_ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps)
302 {
303 #if PRINTF_ADVANCED_ENABLE
304     long long int a;
305     long long int b;
306     long long int c;
307 
308     unsigned long long int ua;
309     unsigned long long int ub;
310     unsigned long long int uc;
311     unsigned long long int uc_param;
312 #else
313     int a;
314     int b;
315     int c;
316 
317     unsigned int ua;
318     unsigned int ub;
319     unsigned int uc;
320     unsigned int uc_param;
321 #endif /* PRINTF_ADVANCED_ENABLE */
322 
323     int32_t nlen;
324     char *nstrp;
325 
326     nlen     = 0;
327     nstrp    = numstr;
328     *nstrp++ = '\0';
329 
330 #if !(PRINTF_ADVANCED_ENABLE > 0)
331     neg = 0;
332 #endif
333 
334 #if PRINTF_ADVANCED_ENABLE
335     a        = 0;
336     b        = 0;
337     c        = 0;
338     ua       = 0ULL;
339     ub       = 0ULL;
340     uc       = 0ULL;
341     uc_param = 0ULL;
342 #else
343     a        = 0;
344     b        = 0;
345     c        = 0;
346     ua       = 0U;
347     ub       = 0U;
348     uc       = 0U;
349     uc_param = 0U;
350 #endif /* PRINTF_ADVANCED_ENABLE */
351 
352     (void)a;
353     (void)b;
354     (void)c;
355     (void)ua;
356     (void)ub;
357     (void)uc;
358     (void)uc_param;
359     (void)neg;
360     /*
361      * Fix MISRA issue: CID 15985711 (#15 of 15): MISRA C-2012 Control Flow Expressions (MISRA C-2012 Rule 14.3)
362      * misra_c_2012_rule_14_3_violation: Execution cannot reach this statement: a = *((int *)nump);
363      */
364 #if PRINTF_ADVANCED_ENABLE
365     if (0 != neg)
366     {
367 #if PRINTF_ADVANCED_ENABLE
368         a = *(long long int *)nump;
369 #else
370         a = *(int *)nump;
371 #endif /* PRINTF_ADVANCED_ENABLE */
372         if (a == 0)
373         {
374             *nstrp = '0';
375             ++nlen;
376             return nlen;
377         }
378         while (a != 0)
379         {
380 #if PRINTF_ADVANCED_ENABLE
381             b = (long long int)a / (long long int)radix;
382             c = (long long int)a - ((long long int)b * (long long int)radix);
383             if (c < 0)
384             {
385                 uc       = (unsigned long long int)c;
386                 uc_param = ~uc;
387                 c        = (long long int)uc_param + 1 + (long long int)'0';
388             }
389 #else
390             b = (int)a / (int)radix;
391             c = (int)a - ((int)b * (int)radix);
392             if (c < 0)
393             {
394                 uc       = (unsigned int)c;
395                 uc_param = ~uc;
396                 c        = (int)uc_param + 1 + (int)'0';
397             }
398 #endif /* PRINTF_ADVANCED_ENABLE */
399             else
400             {
401                 c = c + (int)'0';
402             }
403             a        = b;
404             *nstrp++ = (char)c;
405             ++nlen;
406         }
407     }
408     else
409 #endif /* PRINTF_ADVANCED_ENABLE */
410     {
411 #if PRINTF_ADVANCED_ENABLE
412         ua = *(unsigned long long int *)nump;
413 #else
414         ua = *(unsigned int *)nump;
415 #endif /* PRINTF_ADVANCED_ENABLE */
416         if (ua == 0U)
417         {
418             *nstrp = '0';
419             ++nlen;
420             return nlen;
421         }
422         while (ua != 0U)
423         {
424 #if PRINTF_ADVANCED_ENABLE
425             ub = (unsigned long long int)ua / (unsigned long long int)radix;
426             uc = (unsigned long long int)ua - ((unsigned long long int)ub * (unsigned long long int)radix);
427 #else
428             ub = ua / (unsigned int)radix;
429             uc = ua - (ub * (unsigned int)radix);
430 #endif /* PRINTF_ADVANCED_ENABLE */
431 
432             if (uc < 10U)
433             {
434                 uc = uc + (unsigned int)'0';
435             }
436             else
437             {
438                 uc = uc - 10U + (unsigned int)(use_caps ? 'A' : 'a');
439             }
440             ua       = ub;
441             *nstrp++ = (char)uc;
442             ++nlen;
443         }
444     }
445     return nlen;
446 }
447 
448 #if PRINTF_FLOAT_ENABLE
449 /*!
450  * @brief Converts a floating radix number to a string and return its length.
451  *
452  * @param[in] numstr            Converted string of the number.
453  * @param[in] nump              Pointer to the number.
454  * @param[in] radix             The radix to be converted to.
455  * @param[in] precision_width   Specify the precision width.
456 
457  * @return Length of the converted string.
458  */
DbgConsole_ConvertFloatRadixNumToString(char * numstr,void * nump,int32_t radix,uint32_t precision_width)459 static int32_t DbgConsole_ConvertFloatRadixNumToString(char *numstr,
460                                                        void *nump,
461                                                        int32_t radix,
462                                                        uint32_t precision_width)
463 {
464     int32_t a;
465     int32_t b;
466     int32_t c;
467     uint32_t i;
468     double fa;
469     double dc;
470     double fb;
471     double r;
472     double fractpart;
473     double intpart;
474 
475     int32_t nlen;
476     char *nstrp;
477     nlen     = 0;
478     nstrp    = numstr;
479     *nstrp++ = '\0';
480     r        = *(double *)nump;
481     if (0.0 == r)
482     {
483         *nstrp = '0';
484         ++nlen;
485         return nlen;
486     }
487     fractpart = modf((double)r, (double *)&intpart);
488     /* Process fractional part. */
489     for (i = 0; i < precision_width; i++)
490     {
491         fractpart *= (double)radix;
492     }
493     if (r >= 0.0)
494     {
495         fa = fractpart + (double)0.5;
496         if (fa >= pow((double)10, (double)precision_width))
497         {
498             intpart++;
499         }
500     }
501     else
502     {
503         fa = fractpart - (double)0.5;
504         if (fa <= -pow((double)10, (double)precision_width))
505         {
506             intpart--;
507         }
508     }
509     for (i = 0; i < precision_width; i++)
510     {
511         fb = fa / (double)radix;
512         dc = (fa - (double)(long long int)fb * (double)radix);
513         c  = (int32_t)dc;
514         if (c < 0)
515         {
516             c = (int32_t)'0' - c;
517         }
518         else
519         {
520             c = c + '0';
521         }
522         fa       = fb;
523         *nstrp++ = (char)c;
524         ++nlen;
525     }
526     *nstrp++ = (char)'.';
527     ++nlen;
528     a = (int32_t)intpart;
529     if (a == 0)
530     {
531         *nstrp++ = '0';
532         ++nlen;
533     }
534     else
535     {
536         while (a != 0)
537         {
538             b = (int32_t)a / (int32_t)radix;
539             c = (int32_t)a - ((int32_t)b * (int32_t)radix);
540             if (c < 0)
541             {
542                 c = (int32_t)'0' - c;
543             }
544             else
545             {
546                 c = c + '0';
547             }
548             a        = b;
549             *nstrp++ = (char)c;
550             ++nlen;
551         }
552     }
553     return nlen;
554 }
555 #endif /* PRINTF_FLOAT_ENABLE */
556 
557 /*!
558  * @brief This function outputs its parameters according to a formatted string.
559  *
560  * @note I/O is performed by calling given function pointer using following
561  * (*func_ptr)(c);
562  *
563  * @param[in] func_ptr  Function to put character out.
564  * @param[in] fmt       Format string for printf.
565  * @param[in] ap        Arguments to printf.
566  *
567  * @return Number of characters
568  */
DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr,const char * fmt,va_list ap)569 static int DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr, const char *fmt, va_list ap)
570 {
571     /* va_list ap; */
572     const char *p;
573     char c;
574 
575     char vstr[33];
576     char *vstrp  = NULL;
577     int32_t vlen = 0;
578 
579     bool done;
580     int32_t count = 0;
581 
582     uint32_t field_width;
583     uint32_t precision_width;
584     char *sval;
585     int32_t cval;
586     bool use_caps;
587     uint8_t radix = 0;
588 
589 #if PRINTF_ADVANCED_ENABLE
590     uint32_t flags_used;
591     char schar;
592     bool dschar;
593     long long int ival;
594     unsigned long long int uval = 0;
595     bool valid_precision_width;
596 #else
597     int ival;
598     unsigned int uval = 0;
599 #endif /* PRINTF_ADVANCED_ENABLE */
600 
601 #if PRINTF_FLOAT_ENABLE
602     double fval;
603 #endif /* PRINTF_FLOAT_ENABLE */
604 
605     /* Start parsing apart the format string and display appropriate formats and data. */
606     p = fmt;
607     while (true)
608     {
609         if ('\0' == *p)
610         {
611             break;
612         }
613         c = *p;
614         /*
615          * All formats begin with a '%' marker.  Special chars like
616          * '\n' or '\t' are normally converted to the appropriate
617          * character by the __compiler__.  Thus, no need for this
618          * routine to account for the '\' character.
619          */
620         if (c != '%')
621         {
622             (void)func_ptr(c);
623             count++;
624             p++;
625             /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
626             continue;
627         }
628 
629         use_caps = true;
630 
631 #if PRINTF_ADVANCED_ENABLE
632         /* First check for specification modifier flags. */
633         flags_used = 0;
634         done       = false;
635         while (!done)
636         {
637             switch (*++p)
638             {
639                 case '-':
640                     flags_used |= (uint32_t)kPRINTF_Minus;
641                     break;
642                 case '+':
643                     flags_used |= (uint32_t)kPRINTF_Plus;
644                     break;
645                 case ' ':
646                     flags_used |= (uint32_t)kPRINTF_Space;
647                     break;
648                 case '0':
649                     flags_used |= (uint32_t)kPRINTF_Zero;
650                     break;
651                 case '#':
652                     flags_used |= (uint32_t)kPRINTF_Pound;
653                     break;
654                 default:
655                     /* We've gone one char too far. */
656                     --p;
657                     done = true;
658                     break;
659             }
660         }
661 #endif /* PRINTF_ADVANCED_ENABLE */
662 
663         /* Next check for minimum field width. */
664         field_width = 0;
665         done        = false;
666         while (!done)
667         {
668             c = *++p;
669             if ((c >= '0') && (c <= '9'))
670             {
671                 field_width = (field_width * 10U) + ((uint32_t)c - (uint32_t)'0');
672             }
673 #if PRINTF_ADVANCED_ENABLE
674             else if (c == '*')
675             {
676                 field_width = (uint32_t)va_arg(ap, unsigned int);
677             }
678 #endif /* PRINTF_ADVANCED_ENABLE */
679             else
680             {
681                 /* We've gone one char too far. */
682                 --p;
683                 done = true;
684             }
685         }
686         /* Next check for the width and precision field separator. */
687 #if (PRINTF_ADVANCED_ENABLE || PRINTF_FLOAT_ENABLE)
688         precision_width = 6U; /* MISRA C-2012 Rule 2.2 */
689 #endif
690 #if PRINTF_ADVANCED_ENABLE
691         valid_precision_width = false;
692 #endif /* PRINTF_ADVANCED_ENABLE */
693         if (*++p == '.')
694         {
695             /* Must get precision field width, if present. */
696             precision_width = 0U;
697             done            = false;
698             while (!done)
699             {
700                 c = *++p;
701                 if ((c >= '0') && (c <= '9'))
702                 {
703                     precision_width = (precision_width * 10U) + ((uint32_t)c - (uint32_t)'0');
704 #if PRINTF_ADVANCED_ENABLE
705                     valid_precision_width = true;
706 #endif /* PRINTF_ADVANCED_ENABLE */
707                 }
708 #if PRINTF_ADVANCED_ENABLE
709                 else if (c == '*')
710                 {
711                     precision_width       = (uint32_t)va_arg(ap, unsigned int);
712                     valid_precision_width = true;
713                 }
714 #endif /* PRINTF_ADVANCED_ENABLE */
715                 else
716                 {
717                     /* We've gone one char too far. */
718                     --p;
719                     done = true;
720                 }
721             }
722         }
723         else
724         {
725             /* We've gone one char too far. */
726             --p;
727         }
728 #if PRINTF_ADVANCED_ENABLE
729         /*
730          * Check for the length modifier.
731          */
732         switch (/* c = */ *++p)
733         {
734             case 'h':
735                 if (*++p != 'h')
736                 {
737                     flags_used |= (uint32_t)kPRINTF_LengthShortInt;
738                     --p;
739                 }
740                 else
741                 {
742                     flags_used |= (uint32_t)kPRINTF_LengthChar;
743                 }
744                 break;
745             case 'l':
746                 if (*++p != 'l')
747                 {
748                     flags_used |= (uint32_t)kPRINTF_LengthLongInt;
749                     --p;
750                 }
751                 else
752                 {
753                     flags_used |= (uint32_t)kPRINTF_LengthLongLongInt;
754                 }
755                 break;
756             case 'z':
757                 if (sizeof(size_t) == sizeof(uint32_t))
758                 {
759                     flags_used |= (uint32_t)kPRINTF_LengthLongInt;
760                 }
761                 else if (sizeof(size_t) == (2U * sizeof(uint32_t)))
762                 {
763                     flags_used |= (uint32_t)kPRINTF_LengthLongLongInt;
764                 }
765                 else if (sizeof(size_t) == sizeof(uint16_t))
766                 {
767                     flags_used |= (uint32_t)kPRINTF_LengthShortInt;
768                 }
769                 else
770                 {
771                     /* MISRA C-2012 Rule 15.7 */
772                 }
773                 break;
774             default:
775                 /* we've gone one char too far */
776                 --p;
777                 break;
778         }
779 #endif /* PRINTF_ADVANCED_ENABLE */
780         /* Now we're ready to examine the format. */
781         c = *++p;
782         {
783             if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') ||
784                 (c == 'b') || (c == 'p') || (c == 'u'))
785             {
786                 if ((c == 'd') || (c == 'i'))
787                 {
788 #if PRINTF_ADVANCED_ENABLE
789                     if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongLongInt))
790                     {
791                         ival = (long long int)va_arg(ap, long long int);
792                     }
793                     else if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongInt))
794                     {
795                         ival = (long int)va_arg(ap, long int);
796                     }
797                     else
798 #endif /* PRINTF_ADVANCED_ENABLE */
799                     {
800                         ival = (int)va_arg(ap, int);
801                     }
802                     vlen  = DbgConsole_ConvertRadixNumToString(vstr, &ival, 1, 10, use_caps);
803                     vstrp = &vstr[vlen];
804 #if PRINTF_ADVANCED_ENABLE
805                     if (ival < 0)
806                     {
807                         schar = '-';
808                         ++vlen;
809                     }
810                     else
811                     {
812                         if (0U != (flags_used & (uint32_t)kPRINTF_Plus))
813                         {
814                             schar = '+';
815                             ++vlen;
816                         }
817                         else
818                         {
819                             if (0U != (flags_used & (uint32_t)kPRINTF_Space))
820                             {
821                                 schar = ' ';
822                                 ++vlen;
823                             }
824                             else
825                             {
826                                 schar = '\0';
827                             }
828                         }
829                     }
830                     dschar = false;
831                     /* Do the ZERO pad. */
832                     if (0U != (flags_used & (uint32_t)kPRINTF_Zero))
833                     {
834                         if ('\0' != schar)
835                         {
836                             (void)func_ptr(schar);
837                             count++;
838                         }
839                         dschar = true;
840 
841                         DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr);
842                         vlen = (int32_t)field_width;
843                     }
844                     else
845                     {
846                         if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
847                         {
848                             DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
849                             if ('\0' != schar)
850                             {
851                                 (void)func_ptr(schar);
852                                 count++;
853                             }
854                             dschar = true;
855                         }
856                     }
857                     /* The string was built in reverse order, now display in correct order. */
858                     if ((!dschar) && ('\0' != schar))
859                     {
860                         (void)func_ptr(schar);
861                         count++;
862                     }
863 #endif /* PRINTF_ADVANCED_ENABLE */
864                 }
865 
866 #if PRINTF_FLOAT_ENABLE
867                 if ((c == 'f') || (c == 'F'))
868                 {
869                     fval  = (double)va_arg(ap, double);
870                     vlen  = DbgConsole_ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
871                     vstrp = &vstr[vlen];
872 
873 #if PRINTF_ADVANCED_ENABLE
874                     if (fval < 0.0)
875                     {
876                         schar = '-';
877                         ++vlen;
878                     }
879                     else
880                     {
881                         if (0U != (flags_used & (uint32_t)kPRINTF_Plus))
882                         {
883                             schar = '+';
884                             ++vlen;
885                         }
886                         else
887                         {
888                             if (0U != (flags_used & (uint32_t)kPRINTF_Space))
889                             {
890                                 schar = ' ';
891                                 ++vlen;
892                             }
893                             else
894                             {
895                                 schar = '\0';
896                             }
897                         }
898                     }
899                     dschar = false;
900                     if (0U != (flags_used & (uint32_t)kPRINTF_Zero))
901                     {
902                         if ('\0' != schar)
903                         {
904                             (void)func_ptr(schar);
905                             count++;
906                         }
907                         dschar = true;
908                         DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr);
909                         vlen = (int32_t)field_width;
910                     }
911                     else
912                     {
913                         if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
914                         {
915                             DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
916                             if ('\0' != schar)
917                             {
918                                 (void)func_ptr(schar);
919                                 count++;
920                             }
921                             dschar = true;
922                         }
923                     }
924                     if ((!dschar) && ('\0' != schar))
925                     {
926                         (void)func_ptr(schar);
927                         count++;
928                     }
929 #endif /* PRINTF_ADVANCED_ENABLE */
930                 }
931 #endif /* PRINTF_FLOAT_ENABLE */
932                 if ((c == 'X') || (c == 'x'))
933                 {
934                     if (c == 'x')
935                     {
936                         use_caps = false;
937                     }
938 #if PRINTF_ADVANCED_ENABLE
939                     if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongLongInt))
940                     {
941                         uval = (unsigned long long int)va_arg(ap, unsigned long long int);
942                     }
943                     else if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongInt))
944                     {
945                         uval = (unsigned long int)va_arg(ap, unsigned long int);
946                     }
947                     else
948 #endif /* PRINTF_ADVANCED_ENABLE */
949                     {
950                         uval = (unsigned int)va_arg(ap, unsigned int);
951                     }
952                     vlen  = DbgConsole_ConvertRadixNumToString(vstr, &uval, 0, 16, use_caps);
953                     vstrp = &vstr[vlen];
954 
955 #if PRINTF_ADVANCED_ENABLE
956                     dschar = false;
957                     if (0U != (flags_used & (uint32_t)kPRINTF_Zero))
958                     {
959                         if (0U != (flags_used & (uint32_t)kPRINTF_Pound))
960                         {
961                             (void)func_ptr('0');
962                             (void)func_ptr((use_caps ? 'X' : 'x'));
963                             count += 2;
964                             /*vlen += 2;*/
965                             dschar = true;
966                         }
967                         DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr);
968                         vlen = (int32_t)field_width;
969                     }
970                     else
971                     {
972                         if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
973                         {
974                             if (0U != (flags_used & (uint32_t)kPRINTF_Pound))
975                             {
976                                 vlen += 2;
977                             }
978                             DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
979                             if (0U != (flags_used & (uint32_t)kPRINTF_Pound))
980                             {
981                                 (void)func_ptr('0');
982                                 (void)func_ptr(use_caps ? 'X' : 'x');
983                                 count += 2;
984 
985                                 dschar = true;
986                             }
987                         }
988                     }
989 
990                     if ((0U != (flags_used & (uint32_t)kPRINTF_Pound)) && (!dschar))
991                     {
992                         (void)func_ptr('0');
993                         (void)func_ptr(use_caps ? 'X' : 'x');
994                         count += 2;
995                         vlen += 2;
996                     }
997 #endif /* PRINTF_ADVANCED_ENABLE */
998                 }
999                 if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u'))
1000                 {
1001                     if ('p' == c)
1002                     {
1003                         /*
1004                          * Fix MISRA issue: CID 16209727 (#15 of 15): MISRA C-2012 Pointer Type Conversions (MISRA
1005                          * C-2012 Rule 11.6)
1006                          * 1. misra_c_2012_rule_11_6_violation: The expression va_arg (ap, void *) of type void * is
1007                          * cast to type unsigned int.
1008                          *
1009                          * Orignal code: uval = (unsigned int)va_arg(ap, void *);
1010                          */
1011                         void *pval;
1012                         pval = (void *)va_arg(ap, void *);
1013                         (void)memcpy((void *)&uval, (void *)&pval, sizeof(void *));
1014                     }
1015                     else
1016                     {
1017 #if PRINTF_ADVANCED_ENABLE
1018                         if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongLongInt))
1019                         {
1020                             uval = (unsigned long long int)va_arg(ap, unsigned long long int);
1021                         }
1022                         else if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongInt))
1023                         {
1024                             uval = (unsigned long int)va_arg(ap, unsigned long int);
1025                         }
1026                         else
1027 #endif /* PRINTF_ADVANCED_ENABLE */
1028                         {
1029                             uval = (unsigned int)va_arg(ap, unsigned int);
1030                         }
1031                     }
1032                     switch (c)
1033                     {
1034                         case 'o':
1035                             radix = 8;
1036                             break;
1037                         case 'b':
1038                             radix = 2;
1039                             break;
1040                         case 'p':
1041                             radix = 16;
1042                             break;
1043                         case 'u':
1044                             radix = 10;
1045                             break;
1046                         default:
1047                             /* MISRA C-2012 Rule 16.4 */
1048                             break;
1049                     }
1050                     vlen  = DbgConsole_ConvertRadixNumToString(vstr, &uval, 0, (int32_t)radix, use_caps);
1051                     vstrp = &vstr[vlen];
1052 #if PRINTF_ADVANCED_ENABLE
1053                     if (0U != (flags_used & (uint32_t)kPRINTF_Zero))
1054                     {
1055                         DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr);
1056                         vlen = (int32_t)field_width;
1057                     }
1058                     else
1059                     {
1060                         if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
1061                         {
1062                             DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
1063                         }
1064                     }
1065 #endif /* PRINTF_ADVANCED_ENABLE */
1066                 }
1067 #if !PRINTF_ADVANCED_ENABLE
1068                 DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
1069 #endif /* !PRINTF_ADVANCED_ENABLE */
1070                 if (vstrp != NULL)
1071                 {
1072                     while ('\0' != *vstrp)
1073                     {
1074                         (void)func_ptr(*vstrp--);
1075                         count++;
1076                     }
1077                 }
1078 #if PRINTF_ADVANCED_ENABLE
1079                 if (0U != (flags_used & (uint32_t)kPRINTF_Minus))
1080                 {
1081                     DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
1082                 }
1083 #endif /* PRINTF_ADVANCED_ENABLE */
1084             }
1085             else if (c == 'c')
1086             {
1087                 cval = (int32_t)va_arg(ap, unsigned int);
1088                 (void)func_ptr(cval);
1089                 count++;
1090             }
1091             else if (c == 's')
1092             {
1093                 sval = (char *)va_arg(ap, char *);
1094                 if (NULL != sval)
1095                 {
1096 #if PRINTF_ADVANCED_ENABLE
1097                     if (valid_precision_width)
1098                     {
1099                         vlen = (int32_t)precision_width;
1100                     }
1101                     else
1102                     {
1103                         vlen = (int32_t)strlen(sval);
1104                     }
1105 #else
1106                     vlen = (int32_t)strlen(sval);
1107 #endif /* PRINTF_ADVANCED_ENABLE */
1108 #if PRINTF_ADVANCED_ENABLE
1109                     if (0U == (flags_used & (uint32_t)kPRINTF_Minus))
1110 #endif /* PRINTF_ADVANCED_ENABLE */
1111                     {
1112                         DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
1113                     }
1114 
1115 #if PRINTF_ADVANCED_ENABLE
1116                     if (valid_precision_width)
1117                     {
1118                         while (('\0' != *sval) && (vlen > 0))
1119                         {
1120                             (void)func_ptr(*sval++);
1121                             count++;
1122                             vlen--;
1123                         }
1124                         /* In case that vlen sval is shorter than vlen */
1125                         vlen = (int32_t)precision_width - vlen;
1126                     }
1127                     else
1128                     {
1129 #endif /* PRINTF_ADVANCED_ENABLE */
1130                         while ('\0' != *sval)
1131                         {
1132                             (void)func_ptr(*sval++);
1133                             count++;
1134                         }
1135 #if PRINTF_ADVANCED_ENABLE
1136                     }
1137 #endif /* PRINTF_ADVANCED_ENABLE */
1138 
1139 #if PRINTF_ADVANCED_ENABLE
1140                     if (0U != (flags_used & (uint32_t)kPRINTF_Minus))
1141                     {
1142                         DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr);
1143                     }
1144 #endif /* PRINTF_ADVANCED_ENABLE */
1145                 }
1146             }
1147             else
1148             {
1149                 (void)func_ptr(c);
1150                 count++;
1151             }
1152         }
1153         p++;
1154     }
1155     return count;
1156 }
1157 
1158 #endif /* SDK_DEBUGCONSOLE */
1159 
1160 /*************Code to support toolchain's printf, scanf *******************************/
1161 /* These function __write and __read is used to support IAR toolchain to printf and scanf*/
1162 #if (defined(__ICCARM__))
1163 #if defined(SDK_DEBUGCONSOLE_UART)
1164 #pragma weak __write
1165 size_t __write(int handle, const unsigned char *buffer, size_t size);
__write(int handle,const unsigned char * buffer,size_t size)1166 size_t __write(int handle, const unsigned char *buffer, size_t size)
1167 {
1168     size_t ret;
1169     if (NULL == buffer)
1170     {
1171         /*
1172          * This means that we should flush internal buffers.  Since we don't we just return.
1173          * (Remember, "handle" == -1 means that all handles should be flushed.)
1174          */
1175         ret = (size_t)0;
1176     }
1177     else if ((handle != 1) && (handle != 2))
1178     {
1179         /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure.
1180          */
1181         ret = (size_t)-1;
1182     }
1183     else if (kSerialPort_None == s_debugConsole.serial_port_type)
1184     {
1185         /* Do nothing if the debug UART is not initialized. */
1186         ret = (size_t)-1;
1187     }
1188     else
1189     {
1190         /* Send data. */
1191         (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], buffer, size);
1192         ret = size;
1193     }
1194     return ret;
1195 }
1196 
1197 #pragma weak __read
1198 size_t __read(int handle, unsigned char *buffer, size_t size);
__read(int handle,unsigned char * buffer,size_t size)1199 size_t __read(int handle, unsigned char *buffer, size_t size)
1200 {
1201     size_t ret;
1202     /* This function only reads from "standard in", for all other file  handles it returns failure. */
1203     if (handle != 0)
1204     {
1205         ret = ((size_t)-1);
1206     }
1207     else if (kSerialPort_None == s_debugConsole.serial_port_type)
1208     {
1209         /* Do nothing if the debug UART is not initialized. */
1210         ret = ((size_t)-1);
1211     }
1212     else
1213     {
1214         /* Receive data. */
1215         (void)s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], buffer, size);
1216         ret = size;
1217     }
1218     return ret;
1219 }
1220 #endif /* SDK_DEBUGCONSOLE_UART */
1221 
1222 /* support LPC Xpresso with RedLib */
1223 #elif (defined(__REDLIB__))
1224 
1225 #if (defined(SDK_DEBUGCONSOLE_UART))
__sys_write(int handle,char * buffer,int size)1226 int __attribute__((weak)) __sys_write(int handle, char *buffer, int size)
1227 {
1228     if (NULL == buffer)
1229     {
1230         /* return -1 if error. */
1231         return -1;
1232     }
1233 
1234     /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
1235     if ((handle != 1) && (handle != 2))
1236     {
1237         return -1;
1238     }
1239 
1240     /* Do nothing if the debug UART is not initialized. */
1241     if (kSerialPort_None == s_debugConsole.serial_port_type)
1242     {
1243         return -1;
1244     }
1245 
1246     /* Send data. */
1247     (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size);
1248 
1249     return 0;
1250 }
1251 
__sys_readc(void)1252 int __attribute__((weak)) __sys_readc(void)
1253 {
1254     char tmp;
1255     /* Do nothing if the debug UART is not initialized. */
1256     if (kSerialPort_None == s_debugConsole.serial_port_type)
1257     {
1258         return -1;
1259     }
1260 
1261     /* Receive data. */
1262     s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)&tmp, sizeof(tmp));
1263 
1264     return tmp;
1265 }
1266 #endif /* SDK_DEBUGCONSOLE_UART */
1267 
1268 /* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/
1269 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
1270 #if defined(SDK_DEBUGCONSOLE_UART)
1271 #if defined(__CC_ARM)
1272 struct __FILE
1273 {
1274     int handle;
1275     /*
1276      * Whatever you require here. If the only file you are using is standard output using printf() for debugging,
1277      * no file handling is required.
1278      */
1279 };
1280 #endif
1281 
1282 /* FILE is typedef in stdio.h. */
1283 #pragma weak __stdout
1284 #pragma weak __stdin
1285 FILE __stdout;
1286 FILE __stdin;
1287 
1288 #pragma weak fputc
fputc(int ch,FILE * f)1289 int fputc(int ch, FILE *f)
1290 {
1291     /* Do nothing if the debug UART is not initialized. */
1292     if (kSerialPort_None == s_debugConsole.serial_port_type)
1293     {
1294         return -1;
1295     }
1296 
1297     /* Send data. */
1298     (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ch), 1);
1299     return 1;
1300 }
1301 
1302 #pragma weak fgetc
fgetc(FILE * f)1303 int fgetc(FILE *f)
1304 {
1305     char ch;
1306     /* Do nothing if the debug UART is not initialized. */
1307     if (kSerialPort_None == s_debugConsole.serial_port_type)
1308     {
1309         return -1;
1310     }
1311 
1312     /* Receive data. */
1313     s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ch), 1);
1314     return ch;
1315 }
1316 
1317 /*
1318  * Terminate the program, passing a return code back to the user.
1319  * This function may not return.
1320  */
_sys_exit(int returncode)1321 void _sys_exit(int returncode)
1322 {
1323     while (1)
1324     {
1325     }
1326 }
1327 
1328 /*
1329  * Writes a character to the output channel. This function is used
1330  * for last-resort error message output.
1331  */
_ttywrch(int ch)1332 void _ttywrch(int ch)
1333 {
1334     char ench = ch;
1335     /* Send data. */
1336     s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ench), 1);
1337 }
1338 
_sys_command_string(char * cmd,int len)1339 char *_sys_command_string(char *cmd, int len)
1340 {
1341     return (cmd);
1342 }
1343 #endif /* SDK_DEBUGCONSOLE_UART */
1344 
1345 /* These function __write_r and __read_r are used to support Xtensa Clang toolchain to printf and scanf */
1346 #elif defined(__XTENSA__) && defined(__XT_CLANG__)
1347 #if defined(SDK_DEBUGCONSOLE_UART)
1348 
1349 int __attribute__((weak)) _write_r(void *ptr, int handle, char *buffer, int size);
_write_r(void * ptr,int handle,char * buffer,int size)1350 int __attribute__((weak)) _write_r(void *ptr, int handle, char *buffer, int size)
1351 {
1352     if (NULL == buffer)
1353     {
1354         /* return -1 if error. */
1355         return -1;
1356     }
1357 
1358     /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
1359     if ((handle != 1) && (handle != 2))
1360     {
1361         return -1;
1362     }
1363 
1364     /* Do nothing if the debug UART is not initialized. */
1365     if (kSerialPort_None == s_debugConsole.serial_port_type)
1366     {
1367         return -1;
1368     }
1369 
1370     /* Send data. */
1371     (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size);
1372 
1373     return size;
1374 }
1375 
1376 int __attribute__((weak)) _read_r(void *ptr, int handle, char *buffer, int size);
_read_r(void * ptr,int handle,char * buffer,int size)1377 int __attribute__((weak)) _read_r(void *ptr, int handle, char *buffer, int size)
1378 {
1379     /* This function only reads from "standard in", for all other file handles it returns failure. */
1380     if (handle != 0)
1381     {
1382         return -1;
1383     }
1384 
1385     /* Do nothing if the debug UART is not initialized. */
1386     if (kSerialPort_None == s_debugConsole.serial_port_type)
1387     {
1388         return -1;
1389     }
1390 
1391     /* Receive data. */
1392     (void)s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size);
1393     return size;
1394 }
1395 #endif /* SDK_DEBUGCONSOLE_UART */
1396 
1397 /* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/
1398 #elif (defined(__GNUC__))
1399 
1400 #if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \
1401      (defined(__MCUXPRESSO) && (defined(SDK_DEBUGCONSOLE_UART))))
1402 int __attribute__((weak)) _write(int handle, char *buffer, int size);
_write(int handle,char * buffer,int size)1403 int __attribute__((weak)) _write(int handle, char *buffer, int size)
1404 {
1405     if (NULL == buffer)
1406     {
1407         /* return -1 if error. */
1408         return -1;
1409     }
1410 
1411     /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
1412     if ((handle != 1) && (handle != 2))
1413     {
1414         return -1;
1415     }
1416 
1417     /* Do nothing if the debug UART is not initialized. */
1418     if (kSerialPort_None == s_debugConsole.serial_port_type)
1419     {
1420         return -1;
1421     }
1422 
1423     /* Send data. */
1424     (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size);
1425 
1426     return size;
1427 }
1428 
1429 int __attribute__((weak)) _read(int handle, char *buffer, int size);
_read(int handle,char * buffer,int size)1430 int __attribute__((weak)) _read(int handle, char *buffer, int size)
1431 {
1432     /* This function only reads from "standard in", for all other file handles it returns failure. */
1433     if (handle != 0)
1434     {
1435         return -1;
1436     }
1437 
1438     /* Do nothing if the debug UART is not initialized. */
1439     if (kSerialPort_None == s_debugConsole.serial_port_type)
1440     {
1441         return -1;
1442     }
1443 
1444     /* Receive data. */
1445     (void)s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size);
1446     return size;
1447 }
1448 #endif
1449 
1450 #endif /* __ICCARM__ */
1451