printf实现

来源:互联网 发布:办公室自动化软件 编辑:程序博客网 时间:2024/05/07 13:47

详解U-Boot中printf函数的实现

一、printf函数调用关系


1.1fputc和srial_putc的关系

[plain] view plain copy
 print?
  1. /*  
  2.  * Output a single byte to the serial port.  
  3.  */  
  4. void serial_putc (const char c)//发送数据  
  5. {  
  6.     S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);  
  7. #ifdef CONFIG_MODEM_SUPPORT  
  8.     if (be_quiet)  
  9.         return;  
  10. #endif  
  11.   
  12.     /* wait for room in the tx FIFO */  
  13.     while (!(uart->UTRSTAT & 0x2));  
  14.   
  15. #ifdef CONFIG_HWFLOW  
  16.     /* Wait for CTS up */  
  17.     while(hwflow && !(uart->UMSTAT & 0x1))  
  18.         ;  
  19. #endif  
  20.   
  21.     uart->UTXH = c;  
  22.   
  23.     /* If \n, also do \r */  
  24.     if (c == '\n')  
  25.         serial_putc ('\r');  
  26. }  
serial_putc函数是直接和控制相关的,通过UTXH寄存器发送数据。

[plain] view plain copy
 print?
  1. void fputc (int file, const char c)  
  2. {  
  3.     if (file < MAX_FILES)  
  4.         stdio_devices[file]->putc (c);  
  5. }  

这是在console_init_r中设置stdio_devices[]后才有的,其他的是类似的。

1.2putc和fputc的关系

[plain] view plain copy
 print?
  1. void putc (const char c)  
  2. {  
  3. #ifdef CONFIG_SILENT_CONSOLE  
  4.     if (gd->flags & GD_FLG_SILENT)  
  5.         return;  
  6. #endif  
  7.   
  8.     if (gd->flags & GD_FLG_DEVINIT) {  
  9.         /* Send to the standard output */  
  10.         fputc (stdout, c);  
  11.     } else {  
  12.         /* Send directly to the handler */  
  13.         serial_putc (c);  
  14.     }  
  15. }  

这是console_init_r中设置gd->flags & GD_FLG_DEVINIT,也就是串口设备完全初始化之后才有这种关系,其他的函数是类似的。

二、serial_printf (const char *fmt, ...)

serial_printf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用serial_puts函数将临时缓冲中的字符串数据打印到终端中去。
[plain] view plain copy
 print?
  1. void serial_printf (const char *fmt, ...)  
  2. {  
  3.     va_list args;  
  4.     uint i;  
  5.     char printbuffer[CFG_PBSIZE];  
  6.   
  7.     va_start (args, fmt);  
  8.   
  9.     /* For this to work, printbuffer must be larger than  
  10.      * anything we ever want to print.  
  11.      */  
  12.     i = vsprintf (printbuffer, fmt, args);  
  13.     va_end (args);  
  14.   
  15.     serial_puts (printbuffer);  
  16. }  

三、fprintf(int file, const char *fmt, ...)

fprintf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用fputs函数将临时缓冲中的字符串数据打印到终端中去。

[plain] view plain copy
 print?
  1. void fprintf (int file, const char *fmt, ...)  
  2. {  
  3.     va_list args;  
  4.     uint i;  
  5.     char printbuffer[CFG_PBSIZE];  
  6.   
  7.     va_start (args, fmt);  
  8.   
  9.     /* For this to work, printbuffer must be larger than  
  10.      * anything we ever want to print.  
  11.      */  
  12.     i = vsprintf (printbuffer, fmt, args);  
  13.     va_end (args);  
  14.   
  15.     /* Send to desired file */  
  16.     fputs (file, printbuffer);  
  17. }  

四、vprintf(const char *fmt, va_list args)

vprintf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用puts函数将临时缓冲中的字符串数据打印到终端中去。

[plain] view plain copy
 print?
  1. void vprintf (const char *fmt, va_list args)  
  2. {  
  3.     uint i;  
  4.     char printbuffer[CFG_PBSIZE];  
  5.   
  6.     /* For this to work, printbuffer must be larger than  
  7.      * anything we ever want to print.  
  8.      */  
  9.     i = vsprintf (printbuffer, fmt, args);  
  10.   
  11.     /* Print the string */  
  12.     puts (printbuffer);  
  13. }  

五、printf(const char *fmt, ...)

printf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用puts函数将临时缓冲中的字符串数据打印到终端中去。

[plain] view plain copy
 print?
  1. void printf (const char *fmt, ...)  
  2. {  
  3.     va_list args;  
  4.     uint i;  
  5.     char printbuffer[CFG_PBSIZE];  
  6.   
  7.     va_start (args, fmt);  
  8.   
  9.     /* For this to work, printbuffer must be larger than  
  10.      * anything we ever want to print.  
  11.      */  
  12.     i = vsprintf (printbuffer, fmt, args);  
  13.     va_end (args);  
  14.   
  15.     /* Print the string */  
  16.     puts (printbuffer);  
  17. }  

六、小结

serial_printf、vprintf和pringf函数基本相同,都是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用不同的串口输出函数将临时缓冲中的字符串数据打印到终端中去。下面我们就来分析一下va_start、va_eng和vsprintf。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 客厅午睡的母亲穿裙子在线播放 客厅午睡的母亲自拍 客厅里硬搞午睡的母亲视频 对白搞硬沙发午睡的儿子 客厅沙发儿子碎花裙 电影客厅午睡的母亲 客厅午睡以为你是爸爸 客厅弄醒午唾的儿子 客厅搞硬午睡的儿子小说 客厅弄醒穿花裙子午睡的妈电影 在客厅里弄醒午睡的儿子 中午弄醒正在午睡中的护校小 客厅弄醒午睡的妈视频完整迅雷 弄醒客厅午睡花裙子母亲 对白弄醒午睡的儿子 客厅沙发午睡的妈 母亲今晚让你入个够 在客厅里弄醒午睡的 客厅里午睡的花裙子电影 睡在客厅午睡的母亲 客厅弄醒午睡的妈视频 ckm 客厅中弄醒午睡的儿子 艹醒客厅上睡觉的百褶裙 搞硬午睡儿子沙发大战视频 客厅弄醒午睡的在线播放 在客厅穿花裙子午睡的母亲视频 艹客厅沙发午睡 中国小叔子强大嫂 强睡大嫂风间游美 原千岁老公原谅 美人未亡夫原千岁 原千岁在播放 电影让兄弟睡自己老婆 兄弟的老婆3电影 原千岁宠溺儿在线播放 强睡大搜中女主是谁 给男朋友兄弟口 趁老婆喝醉睡着上闺蜜电影 楼上干兄弟老婆 楼下兄弟打牌 强睡年轻女老板韩国 睡兄弟老婆电微电影