可变参数列表---以dbg()为例
在UART驱动的drivers/serial/samsung.h中遇到如下定义:
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG extern void printascii(const char *); static void dbg(const char *fmt, ...) { va_list va; char buff[256]; va_start(va, fmt); vsprintf(buff, fmt, va); va_end(va); printascii(buff); } #else #define dbg(x...) do { } while (0) #endif
在samsung.c中是这样应用的:
dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",ch, uerstat);
1.对于void printascii(const char *);
有如下解释:
printk输出的log到串口上,配置串口用的是bootloader传过来的参数,例如console=ttyS0。
printascii是独立于printk的打印log的方法。printascii是汇编实现的,直接往uart发送寄存器里扔数据。所以在kernel开始,解析参数之前的log,就可以用printascii去看log.
避免空宏引起的warning
内核中由于不同架构的限制,很多时候会用到空宏,在编译的时候,空宏会给出warning,为了避免这样的warning,就可以使用do{}while(0)来定义空宏。
3.可变参数列表dbg(const char *fmt, ...),通过定义于stdarg.h中的宏来实现。
包括一个类型va_list和三个宏--va_start、va_arg和va_end。
(1)va_list va;
(2)va_start(va, fmt);//初始化va,使va指向可变参数部分的第一个参数。
(3)ret=va_arg(va,char);//此处本代码未利用
//va_arg()第一个参数是va_list变量,第二个参数是参数列表里下一个参数的类型
//va_arg返回这个参数的值,并使va_arg指向下一个可变参数
(4)va_end(va);//完成处理
4.vsprintf()
送格式化输出到串中