xiuos/Ubiquitous/XiZi_IIoT/board/rzv2l-m33/rzv_gen/mbed_printf.c

923 lines
31 KiB
C

/* mbed Microcontroller Library
* Copyright (c) 2017-2020 ARM Limited
* Copyright (c) 2021 Renesas Electronics Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Modified by Renesas so functions pass a context down to outbyte().
* outbyte() is implemented elsewhere so that it can pass a context that our
* serial output function. This is all done to allow us to create a printf_raw()
* function that outputs immediately to the UART for emergency output such as an
* abort.
*/
#include <stdbool.h>
#include <limits.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "console.h"
#include "hal_data.h"
#include <arch_interrupt.h>
#if !TARGET_LIKE_MBED
/* Linux implementation is for debug only */
#define MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT 1
#define MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS 6
#define MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_64_BIT 1
#endif
#ifndef MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
#define MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT 0
#endif
#ifndef MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS
#define MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS 6
#endif
#ifndef MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_64_BIT
#define MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_64_BIT 1
#endif
/**
* Check architecture and choose storage data type.
* On 32 bit machines, the default storage type is 32 bit wide
* unless 64 bit integers are enabled in the configuration.
*/
#if INTPTR_MAX == INT32_MAX
#define MBED_SIGNED_NATIVE_TYPE int32_t
#define MBED_UNSIGNED_NATIVE_TYPE uint32_t
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_64_BIT
#define MBED_SIGNED_STORAGE int64_t
#define MBED_UNSIGNED_STORAGE uint64_t
#else
#define MBED_SIGNED_STORAGE int32_t
#define MBED_UNSIGNED_STORAGE uint32_t
#endif
#elif INTPTR_MAX == INT64_MAX
#define MBED_SIGNED_NATIVE_TYPE int64_t
#define MBED_UNSIGNED_NATIVE_TYPE uint64_t
#define MBED_SIGNED_STORAGE int64_t
#define MBED_UNSIGNED_STORAGE uint64_t
#else
#error unsupported architecture
#endif
/**
* Precision defines
*/
#define PRECISION_DEFAULT (INT_MAX)
/**
* max data number of fifi data reg
*/
static const uint32_t SCIF_UART_TX_FIFO_STAGES = 16;
/**
* Enum for storing width modifier.
*/
typedef enum
{
LENGTH_NONE = 0x00,
LENGTH_H = 0x11,
LENGTH_L = 0x21,
LENGTH_J = 0x31,
LENGTH_Z = 0x41,
LENGTH_T = 0x51,
LENGTH_CAPITAL_L = 0x61,
LENGTH_HH = 0x72,
LENGTH_LL = 0x82
} length_t;
/**
* Enum for integer printing type
*/
typedef enum
{
INT_UNSIGNED,
INT_SIGNED,
HEX_LOWER,
HEX_UPPER,
ZERO_NEGATIVE /* special case when printing integer part of double values where it is 0 and the value is negative */
} integer_type_t;
/**
* Prototypes
*/
static void mbed_minimal_formatted_string_integer(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, integer_type_t type, int width_size, bool prepend_zeros, console_t console);
static void mbed_minimal_formatted_string_void_pointer(char *buffer, size_t length, int *result, const void *value, console_t console);
static void mbed_minimal_formatted_string_string(char *buffer, size_t length, int *result, const char *string, size_t precision, console_t console);
/**
* @brief Print a single character, checking for buffer and size overflows.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] data The char to be printed.
* @param[in] console The method of char data control.
*/
static void mbed_minimal_putchar(char *buffer, size_t length, int *result, char data, console_t console)
{
/* only continue if 'result' doesn't overflow */
if ((*result >= 0) && (*result <= INT_MAX - 1))
{
if ((CONSOLE_RAW == console) || (CONSOLE_BUFFERED == console))
{
outbyte(console, data);
*result += 1;
}
else
{
if (buffer)
{
/* write data only if there's enough space */
if ((size_t)*result < length)
{
buffer[*result] = data;
}
}
/* increment 'result' even if data was not written. This ensures that
'mbed_minimal_formatted_string' returns the correct value. */
*result += 1;
}
}
}
/**
* @brief Print integer in signed, unsigned or hexadecimal format.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param type The type of integer format that shall be printed (signed, unsigend or hexadecimal)
* @param width_size The width modifier.
* @param prepend_zeros Flag to prepends zeros when the width_size is greater than 0
* @param[in] console The method of char data control.
*/
static void mbed_minimal_formatted_string_integer(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, integer_type_t type, int width_size, bool prepend_zeros, console_t console)
{
/* allocate 3 digits per byte */
char scratch[sizeof(MBED_UNSIGNED_STORAGE) * 3] = {0};
int index = 0;
bool negative_value = false;
const char filler = prepend_zeros ? '0' : ' ';
if (type == INT_SIGNED)
{
if ((MBED_SIGNED_STORAGE)value < 0)
{
/* get absolute value using two's complement */
value = ~value + 1;
negative_value = true;
}
}
else if (type == ZERO_NEGATIVE)
{
negative_value = true;
}
if (value == 0)
{
scratch[index] = '0';
index++;
}
else
{
/* write numbers in reverse order to scratch pad */
for (; value > 0; index++)
{
if (type == HEX_LOWER || type == HEX_UPPER)
{
/* get least significant byte */
const uint8_t output = value & 0x0F;
static const char int2hex_lower[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
static const char int2hex_upper[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
if (type == HEX_LOWER)
{
scratch[index] = int2hex_lower[output];
}
else
{
scratch[index] = int2hex_upper[output];
}
/* shift value one byte position */
value = value >> 4;
}
else
{
/* use '0' as base and add digit */
scratch[index] = '0' + (value % 10);
/* shift value one decimal position */
value = value / 10;
}
}
}
if (negative_value)
{
if (prepend_zeros)
{
mbed_minimal_putchar(buffer, length, result, '-', console);
}
index++; // add one to index to count '-'
}
// print filler characters
if (width_size > index)
{
for (int i = width_size; i > index; i--)
{
mbed_minimal_putchar(buffer, length, result, filler, console);
}
}
if (negative_value)
{
if (!prepend_zeros)
{
mbed_minimal_putchar(buffer, length, result, '-', console);
}
index--; // Restore index to correct position
}
/* print absolute value of integer */
for (; index > 0; index--)
{
mbed_minimal_putchar(buffer, length, result, scratch[index - 1], console);
}
}
/**
* @brief Print pointer.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The pointer to be printed.
* @param[in] console The method of char data control.
*/
static void mbed_minimal_formatted_string_void_pointer(char *buffer, size_t length, int *result, const void *value, console_t console)
{
/* write leading 0x */
mbed_minimal_putchar(buffer, length, result, '0', console);
mbed_minimal_putchar(buffer, length, result, 'x', console);
/* write rest as a regular hexadecimal number */
mbed_minimal_formatted_string_integer(buffer, length, result, (ptrdiff_t)value, HEX_UPPER, 0, false, console);
}
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
/**
* @brief Write double.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param[in] dec_precision The decimal precision. If PRECISION_DEFAULT MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS is used.
* @param width_size The width modifier.
* @param prepend_zeros Flag to prepends zeros when the width_size is greater than 0
* @param[in] console The method of char data control.
*/
static void mbed_minimal_formatted_string_double(char *buffer, size_t length, int *result, double value, int dec_precision, int width_size, bool prepend_zeros, console_t console)
{
/* get integer part */
MBED_SIGNED_STORAGE integer = value;
if (dec_precision == PRECISION_DEFAULT)
{
dec_precision = MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS;
}
if (dec_precision != 0)
{
width_size -= dec_precision + 1; // decimal precision plus '.'
if (width_size < 0)
{
width_size = 0;
}
}
else
{
value = (value - integer) * 1.0;
if (!((value > -0.5) && (value < 0.5)))
{
integer++;
}
}
/* write integer part */
if (integer == 0 && value < 0)
{
mbed_minimal_formatted_string_integer(buffer, length, result, integer, ZERO_NEGATIVE, width_size, prepend_zeros, console);
}
else
{
mbed_minimal_formatted_string_integer(buffer, length, result, integer, INT_SIGNED, width_size, prepend_zeros, console);
}
if (dec_precision != 0)
{
/* write decimal point */
mbed_minimal_putchar(buffer, length, result, '.', console);
/* get decimal part */
double precision = 1.0;
for (size_t index = 0; index < dec_precision; index++)
{
precision *= 10;
}
/* convert to positive number */
if (value < 0.0)
{
value *= -1.0;
}
MBED_UNSIGNED_STORAGE decimal = value;
/* round up or down */
value -= decimal;
if (!((value > -0.5) && (value < 0.5)))
{
decimal++;
}
/* write decimal part */
mbed_minimal_formatted_string_integer(buffer, length, result, decimal, INT_UNSIGNED, dec_precision, true, console);
}
}
#endif
/**
* @brief Print string with precision.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The string to be printed.
* @param[in] precision The maximum number of characters to be printed.
* @param[in] console The method of char data control.
*/
static void mbed_minimal_formatted_string_string(char *buffer, size_t length, int *result, const char *string, size_t precision, console_t console)
{
while ((*string != '\0') && (precision))
{
mbed_minimal_putchar(buffer, length, result, *string, console);
string++;
precision--;
}
}
/**
* @brief Parse a string to an integer value as long as there are numerical characters in the string
*
* @param[in] string The input string. Has to begin with a numerical character to parse
* @param[out] value The output value.
* @return size_t The number of numerical characters parsed
*/
static size_t parse_string_to_integer(const char *string, int *value)
{
size_t inner_index = 0;
while ((string[inner_index] >= '0') && (string[inner_index] <= '9'))
{
*value = *value * 10 + (string[inner_index] - '0');
inner_index++;
}
return inner_index;
}
/**
* @brief Parse formatted string and invoke write handlers based on type.
*
* @param buffer The buffer to write to, write to stdout if NULL.
* @param[in] length The length of the buffer.
* @param[in] format The formatted string.
* @param[in] arguments The va_list arguments.
* @param[in] console The method of char data control.
*
* @return Number of characters written.
*/
int mbed_minimal_formatted_string(char *buffer, size_t length, const char *format, va_list arguments, console_t console)
{
int result = 0;
bool empty_buffer = false;
/* ensure that function wasn't called with an empty buffer, or with or with
a buffer size that is larger than the maximum 'int' value, or with
a NULL format specifier */
if (format && length <= INT_MAX)
{
/* Make sure that there's always space for the NULL terminator */
if (length > 0)
{
length--;
}
else
{
/* the buffer is empty, there's no place to write the terminator */
empty_buffer = true;
}
/* parse string */
for (size_t index = 0; format[index] != '\0'; index++)
{
/* format specifier begin */
if (format[index] == '%')
{
size_t next_index = index + 1;
/**************************************************************
* skip and ignore flags [-+(space)#]
*************************************************************/
if ((format[next_index] == '-') ||
(format[next_index] == '+') ||
(format[next_index] == ' ') ||
(format[next_index] == '#'))
{
/* skip to next character */
next_index++;
}
/**************************************************************
* look for width and prepending zeros [(number)], skip [*]
*************************************************************/
bool prepend_zeros = false;
int width_size = 0;
if (format[next_index] == '*')
{
/* skip to next character */
next_index++;
/* discard argument */
va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
}
else
{
if (format[next_index] == '0')
{
prepend_zeros = true;
do
{
next_index++;
} while (format[next_index] == '0');
}
/* parse width modifier until not a decimal */
next_index += parse_string_to_integer(&format[next_index], &width_size);
}
/**************************************************************
* look for precision modifier
*************************************************************/
int precision = PRECISION_DEFAULT;
if ((format[next_index] == '.') &&
(format[next_index + 1] == '*'))
{
next_index += 2;
/* read precision from argument list */
precision = va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
}
else if (format[next_index] == '.')
{
/* precision modifier found, reset default to 0 and increment index */
next_index++;
precision = 0;
/* parse precision until not a decimal */
next_index += parse_string_to_integer(&format[next_index], &precision);
}
/**************************************************************
* look for length modifier, default to NONE
*************************************************************/
length_t length_modifier = LENGTH_NONE;
/* look for two character length modifier */
if ((format[next_index] == 'h') && (format[next_index + 1] == 'h'))
{
length_modifier = LENGTH_HH;
}
else if ((format[next_index] == 'l') && (format[next_index + 1] == 'l'))
{
length_modifier = LENGTH_LL;
}
/* look for one character length modifier if two character search failed */
else if (format[next_index] == 'h')
{
length_modifier = LENGTH_H;
}
else if (format[next_index] == 'l')
{
length_modifier = LENGTH_L;
}
else if (format[next_index] == 'j')
{
length_modifier = LENGTH_J;
}
else if (format[next_index] == 'z')
{
length_modifier = LENGTH_Z;
}
else if (format[next_index] == 't')
{
length_modifier = LENGTH_T;
}
else if (format[next_index] == 'L')
{
length_modifier = LENGTH_CAPITAL_L;
}
/* increment index, length is encoded in modifier enum */
next_index += (length_modifier & 0x0F);
/**************************************************************
* read out character - this is a supported format character,
* '\0', or a not suported character
*************************************************************/
char next = format[next_index];
/* signed integer */
if ((next == 'd') || (next == 'i'))
{
MBED_SIGNED_STORAGE value = 0;
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_64_BIT
/* if 64 bit is enabled and the integer types are larger than the native type */
if (((length_modifier == LENGTH_LL) && (sizeof(long long int) > sizeof(MBED_SIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_L) && (sizeof(long int) > sizeof(MBED_SIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_NONE) && (sizeof(int) > sizeof(MBED_SIGNED_NATIVE_TYPE))))
{
/* use 64 bit storage type for readout */
value = va_arg(arguments, MBED_SIGNED_STORAGE);
}
else
#else
/* If 64 bit is not enabled, print %ll[di] rather than truncated value */
if (length_modifier == LENGTH_LL)
{
mbed_minimal_putchar(buffer, length, &result, '%', console);
if (next == '%')
{
// Continue printing loop after `%`
index = next_index;
}
continue;
}
#endif
{
/* use native storage type (which can be 32 or 64 bit) */
value = va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
}
/* constrict value based on length modifier */
switch (length_modifier)
{
case LENGTH_NONE:
value = (int)value;
break;
case LENGTH_HH:
value = (signed char)value;
break;
case LENGTH_H:
value = (short int)value;
break;
case LENGTH_L:
value = (long int)value;
break;
case LENGTH_LL:
value = (long long int)value;
break;
case LENGTH_J:
value = (intmax_t)value;
break;
case LENGTH_T:
value = (ptrdiff_t)value;
break;
default:
break;
}
index = next_index;
mbed_minimal_formatted_string_integer(buffer, length, &result, value, INT_SIGNED, width_size, prepend_zeros, console);
}
/* unsigned integer */
else if ((next == 'u') || (next == 'x') || (next == 'X'))
{
MBED_UNSIGNED_STORAGE value = 0;
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_64_BIT
/* if 64 bit is enabled and the integer types are larger than the native type */
if (((length_modifier == LENGTH_LL) && (sizeof(unsigned long long int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_L) && (sizeof(unsigned long int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_NONE) && (sizeof(unsigned int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))))
{
/* use 64 bit storage type for readout */
value = va_arg(arguments, MBED_UNSIGNED_STORAGE);
}
else
#else
/* If 64 bit is not enabled, print %ll[uxX] rather than truncated value */
if (length_modifier == LENGTH_LL)
{
mbed_minimal_putchar(buffer, length, &result, '%', console);
if (next == '%')
{
// Continue printing loop after `%`
index = next_index;
}
continue;
}
#endif
{
/* use native storage type (which can be 32 or 64 bit) */
value = va_arg(arguments, MBED_UNSIGNED_NATIVE_TYPE);
}
/* constrict value based on length modifier */
switch (length_modifier)
{
case LENGTH_NONE:
value = (unsigned int)value;
break;
case LENGTH_HH:
value = (unsigned char)value;
break;
case LENGTH_H:
value = (unsigned short int)value;
break;
case LENGTH_L:
value = (unsigned long int)value;
break;
case LENGTH_LL:
value = (unsigned long long int)value;
break;
case LENGTH_J:
value = (uintmax_t)value;
break;
case LENGTH_Z:
value = (size_t)value;
break;
case LENGTH_T:
value = (ptrdiff_t)value;
break;
default:
break;
}
index = next_index;
/* write unsigned or hexadecimal */
if (next == 'u')
{
mbed_minimal_formatted_string_integer(buffer, length, &result, value, INT_UNSIGNED, width_size, prepend_zeros, console);
}
else if (next == 'X')
{
mbed_minimal_formatted_string_integer(buffer, length, &result, value, HEX_UPPER, width_size, prepend_zeros, console);
}
else
{
mbed_minimal_formatted_string_integer(buffer, length, &result, value, HEX_LOWER, width_size, prepend_zeros, console);
}
}
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
/* treat all floating points the same */
else if ((next == 'f') || (next == 'F') || (next == 'g') || (next == 'G'))
{
double value = va_arg(arguments, double);
index = next_index;
mbed_minimal_formatted_string_double(buffer, length, &result, value, precision, width_size, prepend_zeros, console);
}
#endif
/* character */
else if (next == 'c')
{
char value = va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
index = next_index;
mbed_minimal_putchar(buffer, length, &result, value, console);
}
/* string */
else if (next == 's')
{
char *value = va_arg(arguments, char *);
index = next_index;
mbed_minimal_formatted_string_string(buffer, length, &result, value, precision, console);
}
/* pointer */
else if (next == 'p')
{
void *value = va_arg(arguments, void *);
index = next_index;
mbed_minimal_formatted_string_void_pointer(buffer, length, &result, value, console);
}
else
{
// Unrecognised, or `%%`. Print the `%` that led us in.
mbed_minimal_putchar(buffer, length, &result, '%', console);
if (next == '%')
{
// Continue printing loop after `%%`
index = next_index;
}
// Otherwise we continue the printing loop after the leading `%`, so an
// unrecognised thing like "Blah = %a" will just come out as "Blah = %a"
}
}
else
/* not a format specifier */
{
/* write normal character */
mbed_minimal_putchar(buffer, length, &result, format[index], console);
}
}
if (buffer && !empty_buffer)
{
/* NULL-terminate the buffer no matter what. We use '<=' to compare instead of '<'
because we know that we initially reserved space for '\0' by decrementing length */
if ((size_t)result <= length)
{
buffer[result] = '\0';
}
else
{
buffer[length] = '\0';
}
}
}
return result;
}
static uint32_t xSerialPortInitialized = 0;
static uint32_t rx_data_full = 0;
static void uart_callback(uart_callback_args_t *const p_arg)
{
if (p_arg->event & UART_EVENT_RX_COMPLETE)
{
rx_data_full = 1;
}
if (p_arg->event & UART_EVENT_TX_COMPLETE)
{
__NOP();
}
if (p_arg->event & UART_EVENT_RX_CHAR)
{
__NOP();
}
if (p_arg->event & UART_EVENT_ERR_PARITY)
{
__NOP();
}
if (p_arg->event & UART_EVENT_ERR_FRAMING)
{
__NOP();
}
if (p_arg->event & UART_EVENT_ERR_OVERFLOW)
{
__NOP();
}
if (p_arg->event & UART_EVENT_BREAK_DETECT)
{
__NOP();
}
if (p_arg->event & UART_EVENT_TX_DATA_EMPTY)
{
__NOP();
}
}
static void outbyte1(console_t console, char c)
{
scif_uart_instance_ctrl_t * p_ctrl = (scif_uart_instance_ctrl_t *)g_uart2.p_ctrl;
uint32_t no_send_data_count = 0;
while (1)
{
// 获取还未发送的数据数量
no_send_data_count = (uint32_t) p_ctrl->p_reg->FDR_b.T;
// 还存在可以发送数据的空间
if (no_send_data_count < SCIF_UART_TX_FIFO_STAGES)
{
p_ctrl->p_reg->FTDR = c;
break;
}
}
}
void outbyte(console_t console, char c)
{
if (!xSerialPortInitialized)
{
g_uart2.p_api->open(g_uart2.p_ctrl, g_uart2.p_cfg);
g_uart2.p_api->callbackSet(g_uart2.p_ctrl, uart_callback, NULL, NULL);
xSerialPortInitialized = 1;
}
/* Standard practice to convert \n to \r\n */
if (c == '\n')
outbyte1(console, '\r');
outbyte1(console, c);
}
int printf_raw(const char *format, ...)
{
console_t console = CONSOLE_RAW;
va_list args;
int ret;
va_start(args, format);
ret = mbed_minimal_formatted_string(NULL, LONG_MAX, format, args, console);
va_end(args);
return ret;
}
int sprintf(char *buffer, const char *format, ...)
{
console_t console = CONSOLE_RAW;
va_list args;
int ret;
va_start(args, format);
ret = mbed_minimal_formatted_string(buffer, LONG_MAX, format, args, console);
va_end(args);
return ret;
}
int snprintf(char *buffer, size_t length, const char *format, ...)
{
console_t console = CONSOLE_RAW;
va_list args;
int ret;
va_start(args, format);
ret = mbed_minimal_formatted_string(buffer, length, format, args, console);
va_end(args);
return ret;
}
signed char scanf_raw(char *data)
{
if (!xSerialPortInitialized)
{
g_uart2.p_api->open(g_uart2.p_ctrl, g_uart2.p_cfg);
g_uart2.p_api->callbackSet(g_uart2.p_ctrl, uart_callback, NULL, NULL);
xSerialPortInitialized = 1;
}
rx_data_full = 0;
g_uart2.p_api->read(g_uart2.p_ctrl, data, 1);
while (rx_data_full == 0)
{
__WFI();
}
return 1;
}