共3条
1/1 1 跳转至页
上传一个类似于linux的printk函数,可以移植到stm32等arm,方便调式。
/*
* Funny?
* Yes
*/
typedef char * va_list;
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
#define va_start(ap, v) (ap = (va_list)&v + _INTSIZEOF(v))
#define va_arg(ap, t) (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define va_end(ap) (ap = (va_list)0)
const char *digits = "0123456789abcdef";
char numbers[68];
static char print_buf[1024];
/*通过SET_FORMAT_TYPE来设置类型,先清除原先的位值,然后再通过或赋值*/
/*这个特别要说明一下FORMAT_TYPE_SIGN_BIT,这个宏定义函数中并没有直接引用*/
/*而是本身就隐藏在其他有符号数的宏定义中,如:FORMAT_TYPE_INT&FORMAT_TYPE_SIGN_BIT=0x0100;*/
/*FORMAT_TYPE_UINT&FORMAT_TYPE_SIGN_BIT=0*/
#define FORMAT_TYPE_MASK 0xff00
#define FORMAT_TYPE_SIGN_BIT 0x100
#define FORMAT_TYPE_NONE 0x000
#define FORMAT_TYPE_CHAR 0x100
#define FORMAT_TYPE_UCHAR 0x200
#define FORMAT_TYPE_SHORT 0x300
#define FORMAT_TYPE_USHORT 0x400
#define FORMAT_TYPE_INT 0x500
#define FORMAT_TYPE_UINT 0x600
#define FORMAT_TYPE_LONG 0x700
#define FORMAT_TYPE_ULONG 0x800
#define FORMAT_TYPE_STR 0xd00
#define FORMAT_TYPE_PTR 0x900
#define FORMAT_TYPE_SIZE_T 0xb00
/*用于取得类型编码,在程序中用于判断*/
#define FORMAT_TYPE(x) ((x) & FORMAT_TYPE_MASK)
#define SET_FORMAT_TYPE(x, t) \
do { \
(x) &= ~FORMAT_TYPE_MASK; \
(x) |= (t); \
} while (0)
/*用于判断是符号型还是无符号型,返回0或1*/
#define FORMAT_SIGNED(x) ( (x) & FORMAT_TYPE_SIGN_BIT )
#define FORMAT_FLAG_MASK 0xff000000
#define FORMAT_FLAG_SPACE 0x10000
#define FORMAT_FLAG_ZEROPAD 0x20000
#define FORMAT_FLAG_LEFT 0x40000
#define FORMAT_FLAG_WIDTH 0x100000
#define FORMAT_FLAG(x) ((x) & FORMAT_FLAG_MASK)
#define SET_FORMAT_FLAG(x, f) ((x) |= (f))
/*下面用来做整行的不同类型的打印,类型有O,X,D,B*/
/*通过SET_FORMAT_BASE来设置类型,先清除原先的位值,然后再通过或赋值*/
#define FORMAT_BASE_MASK 0xff
#define FORMAT_BASE_O 0x08
#define FORMAT_BASE_X 0x10
#define FORMAT_BASE_D 0x0a
#define FORMAT_BASE_B 0x02
/*用于取得BASE,在程序中用于判断*/
#define FORMAT_BASE(x) (FORMAT_BASE_MASK & (x))
#define SET_FORMAT_BASE(x, t)\
do {\
(x) &= ~FORMAT_BASE_MASK;\
(x) |= (t);\
} while (0)
/*
#define do_div(temp,n, base) ( \
int temp ; \
temp = (unsigned int)n % (unsigned int)base;\
n = ((unsigned int)n) / (unsigned int)base;\
temp; )
*/
void *memcpy(void *dest, const void *src, unsigned int count)
{
char *tmp = (char *)dest;
char *s = (char *)src;
while (count--)
{
*tmp++ = *s++;
}
}
char *number(char *str, char *end, int num, int base, unsigned int flags)
{
int i = 0;
int sign = 0;
char *pos = str;
/*有符号并且为负数,因为在内存中存的是它的补码,所以num的值等于它取反+1*/
if(FORMAT_SIGNED(flags) && ((signed int)num 0)
*str++ = numbers[i];
return pos;
}
int format_decode(const char *fmt, unsigned int *flags)
{
const char *start = fmt;
/*下面这两行不能少,把*flags的type位,以防vsnprintf把普通的字符也当做之前保留的格式输出清除,
因为vsnprintf函数中,有个判断语句:if ((FORMAT_TYPE(spec)) == FORMAT_TYPE_NONE) */
*flags &= ~FORMAT_TYPE_MASK;
*flags |= FORMAT_TYPE_NONE;
for (; *fmt; ++fmt) {
if (*fmt == '%')
break;
}
if (fmt != start || !*fmt)
return fmt - start; /*返回‘%’前字符的长度,退出函数,下次再进来肯定相等*/
do {
fmt++;/*指向‘%’之后一个字符*/
switch (*fmt) {
case 'l':
SET_FORMAT_FLAG(*flags, FORMAT_FLAG_WIDTH);
break;
default:
break;
}
} while (0);
SET_FORMAT_BASE(*flags, FORMAT_BASE_D); /*这个在这里有什么作用?*/
switch (*fmt) {
case 'c':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_CHAR);
break;
case 's':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_STR);
break;
case 'o':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_UINT);
SET_FORMAT_BASE(*flags, FORMAT_BASE_O);
break;
case 'x':
case 'X':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_UINT);
SET_FORMAT_BASE(*flags, FORMAT_BASE_X);
break;
case 'd':
case 'i':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_INT);
SET_FORMAT_BASE(*flags, FORMAT_BASE_D);
break;
case 'b':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_UINT);
SET_FORMAT_BASE(*flags, FORMAT_BASE_B);
break;
case 'u':
SET_FORMAT_TYPE(*flags, FORMAT_TYPE_UINT);
SET_FORMAT_BASE(*flags, FORMAT_BASE_D);
break;
default:
break;
}
return ++fmt - start; /*应该等于2,直接写2也行*/
}
int vsnprintf(char *buf, int size, const char *fmt, va_list args)
{
int num;
char *str, *end, c, *s;
int read;
unsigned int spec = 0;
str = buf;
end = buf + size;
if (end end - str)
copy = end -str;
memcpy(str, old_fmt, copy);
}
str += read;
} else if (spec & FORMAT_FLAG_WIDTH) {
//do nothing
} else if (FORMAT_TYPE(spec) == FORMAT_TYPE_CHAR) {
c = (unsigned char)va_arg(args, int);
if (str 0) {
if (str sizeof(print_buf) - 1) {
put_char("error: the string is too long\n");
put_char(print_buf);
} else {
put_char(print_buf);
}
}
关键词: 上传 一个 类似于 linux printk 函数
共3条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动——B站互动赢积分】活动开启啦! | |
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |