这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 上传一个类似于linux的printk函数,可以移植到stm32等arm,方便调

共3条 1/1 1 跳转至

上传一个类似于linux的printk函数,可以移植到stm32等arm,方便调式。

菜鸟
2012-05-15 15:11:05     打赏
/* * 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     函数    

菜鸟
2012-05-15 15:11:45     打赏
2楼
晕 好像很乱 怎么上传附件

院士
2012-05-26 17:49:23     打赏
3楼
请使用编辑器的分享下载上传附件

共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]