新增mr_printf模块

This commit is contained in:
MacRsh
2023-01-20 23:39:41 +08:00
parent f294035e74
commit d4ccb9bf04
3 changed files with 375 additions and 0 deletions

293
device/printf/printf.c Normal file
View File

@@ -0,0 +1,293 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-01-20 MacRsh first version
*/
#include "printf.h"
/** user specification :
* please set the configuration file first !!!
*
* if you want to use the mr_printf library, adapt the following api:
* (must to adapt) mr_putc : output char through the hardware layer, function format: void mr_putc(char data);
*
* then, you can use the following api:
* (can use) mr_printf : such as printf in the libc
*
* maybe you will run out of memory, you can crop mr_printf library
*
*/
#if (USING_MR_PRINTF == __CONFIG_ENABLE)
MR_WEAK void mr_putc(char data)
{
}
int mr_printf(char *fmt, ...)
{
va_list ap;
char putc_buf[20];
unsigned int u_val;
int val, bits, flag;
double f_val;
char *str;
int res = 0;
/* move ap to fmt + sizeof(fmt) */
va_start(ap,fmt);
while (*fmt != '\0')
{
if(*fmt == '%')
{
++ fmt;
/* dispose %.x */
if(*fmt == '.')
{
++ fmt;
flag = (int)(*fmt - '0');
++ fmt;
}
else
{
flag = 187; // N(46) + U(53) + L(44) + L(44) = NULL(187)
}
/* dispose %d,%x,%o,%u,%s,%c,%f */
switch (*fmt)
{
#if (USING_MR_PRINTF_DEC == __CONFIG_ENABLE)
/* printf signed int to DEC */
case 'd':
/* get value */
val = va_arg(ap,int);
if(val < 0)
{
val = - val;
mr_putc('-');
++ res;
}
/* get value bits */
bits = 0;
while(val)
{
putc_buf[bits] = '0' + val % 10;
val /= 10;
++ bits;
}
res += bits;
/* put value bits */
while (bits)
{
-- bits;
mr_putc(putc_buf[bits]);
}
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_DEC */
#if (USING_MR_PRINTF_HEX == __CONFIG_ENABLE)
/* printf unsigned int to HEX */
case 'x':
/* get value */
u_val = va_arg(ap,unsigned int);
/* get value bits */
bits = 0;
while(u_val)
{
putc_buf[bits] = '0' + u_val % 16;
if(putc_buf[bits] > '9')
putc_buf[bits] = 'A' + (putc_buf[bits] - '9' - 1);
u_val /= 16;
++ bits;
}
res += bits;
/* put value bits */
while (bits)
{
-- bits;
mr_putc(putc_buf[bits]);
}
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_HEX */
#if (USING_MR_PRINTF_OCT == __CONFIG_ENABLE)
/* printf unsigned int to OCT */
case 'o':
/* get value */
u_val = va_arg(ap,unsigned int);
/* get value bits */
bits = 0;
while(u_val)
{
putc_buf[bits] = '0' + u_val % 8;
u_val /= 8;
++ bits;
}
res += bits;
/* put value bits */
while (bits)
{
-- bits;
mr_putc(putc_buf[bits]);
}
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_OCT */
#if (USING_MR_PRINTF_UNSIGNED == __CONFIG_ENABLE)
/* printf unsigned int to DEC */
case 'u':
/* get value */
u_val = va_arg(ap,unsigned int);
/* get value bits */
bits = 0;
while(u_val)
{
putc_buf[bits] = '0' + u_val % 10;
u_val /= 10;
++ bits;
}
res += bits;
/* put value bits */
while (bits)
{
-- bits;
mr_putc(putc_buf[bits]);
}
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_UNSIGNED */
#if (USING_MR_PRINTF_CHAR == __CONFIG_ENABLE)
/* printf char */
case 'c':
mr_putc(va_arg(ap,int));
++ res;
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_CHAR */
#if (USING_MR_PRINTF_STRING == __CONFIG_ENABLE)
/* printf string */
case 's':
str = va_arg(ap,char *);
while (*str != '\0')
{
mr_putc(*str);
++ str;
++ res;
}
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_STRING */
#if (USING_MR_PRINTF_FLOAT == __CONFIG_ENABLE)
/* printf float */
case 'f':
/* get value */
f_val = va_arg(ap,double);
if(f_val < 0)
{
f_val = - f_val;
mr_putc('-');
++ res;
}
/* separation int and float */
val = (int)f_val;
f_val -= (double)val;
/* get int value bits */
bits = 0;
if(val == 0)
{
mr_putc('0');
++ res;
}
while (val)
{
putc_buf[bits] = '0' + val % 10;
val /= 10;
++ bits;
}
res += bits;
/* put int value bits */
while (bits)
{
--bits;
mr_putc(putc_buf[bits]);
}
/* dispose float */
if(flag != 0)
{
mr_putc('.');
++ res;
}
if(flag > 6)
flag = 6;
val = (int)((f_val * 1000000.0f) + 0.5f);
/* get float value bits */
bits = 0;
while (bits < 6)
{
putc_buf[bits] = '0' + val % 10;
val /= 10;
++ bits;
}
res += flag;
/* put int value bits */
while (flag)
{
--flag;
-- bits;
mr_putc(putc_buf[bits]);
}
++ fmt;
continue;
#endif /* end of USING_MR_PRINTF_FLOAT */
default:
-- fmt;
mr_putc(*fmt);
++ res;
++ fmt;
continue;
}
}
else
{
mr_putc(*fmt);
++ res;
++ fmt;
}
}
/* set ap = null */
va_end(ap);
return res;
}
#endif /* end of USING_MR_PRINTF */

35
device/printf/printf.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-01-20 MacRsh first version
*/
#ifndef _PRINTF_H_
#define _PRINTF_H_
#include "printf_cfg.h"
#if (USING_MR_PRINTF == __CONFIG_ENABLE)
/* include va_list/va_start/va_end/va_arg */
#include <stdarg.h>
/* Compiler Related Definitions */
#if defined(__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
#define MR_WEAK __attribute__((weak))
#elif (defined (__CC_ARM) || defined(__CLANG_ARM)) /* ARM Compiler */
#define MR_WEAK __weak
#elif defined(__GNUC__) /* GNU GCC Compiler */
#define MR_WEAK __attribute__((weak))
#endif /* end of __IAR_SYSTEMS_ICC__ */
int mr_printf(char *fmt, ...);
#endif /* end of USING_MR_PRINTF */
#endif /* end of _PRINTF_H_ */

View File

@@ -0,0 +1,47 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-01-20 MacRsh first version
*/
#ifndef _PRINTF_CFG_H_
#define _PRINTF_CFG_H_
/** user specification :
* ( __CONFIG_ENABLE ) it means enable function
* ( __CONFIG_DISABLE ) it means disable function
* ( //< must > ) it means this option need user complement
* ( //< const > ) it means this option unchangeable
* ( //< change able > ) it means this option can change, you could change parameter or annotation parameter
* ( //< optional > ) it means this option is optional, not essential
* ( //<<< XXXX >>> ) it means interpretation this define means
*/
#define __CONFIG_ENABLE 1
#define __CONFIG_DISABLE 0
//<---------------------------- FRAME ----------------------------------------->
//< must >
//<<< If you not using mr_device frame, please remove the following include, replace with your chip head-file >>>
#include "device_def.h"
//< change able >
//<<< Using built-in mr_printf >>>
#define USING_MR_PRINTF __CONFIG_ENABLE
//<<< Using the decimal-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_DEC __CONFIG_ENABLE
//<<< Using the hexadecimal-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_HEX __CONFIG_ENABLE
//<<< Using the octal-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_OCT __CONFIG_ENABLE
//<<< Using the unsigned-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_UNSIGNED __CONFIG_ENABLE
//<<< Using the char-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_CHAR __CONFIG_ENABLE
//<<< Using the string-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_STRING __CONFIG_ENABLE
//<<< Using the float-printf mode in the built-in mr_printf >>>
#define USING_MR_PRINTF_FLOAT __CONFIG_DISABLE
#endif /* end of _PRINTF_CFG_H_ */