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

https://blog.csdn.net/ce123_zhouwei/article/details/7364294

详解U-Boot中printf函数的实现
一、printf函数调用关系


1.1fputc和srial_putc的关系
/*
 * Output a single byte to the serial port.
 */
void serial_putc (const char c)//发送数据
{
    S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
#ifdef CONFIG_MODEM_SUPPORT
    if (be_quiet)
        return;
#endif

    /* wait for room in the tx FIFO */
    while (!(uart->UTRSTAT & 0x2));

#ifdef CONFIG_HWFLOW
    /* Wait for CTS up */
    while(hwflow && !(uart->UMSTAT & 0x1))
        ;
#endif

    uart->UTXH = c;

    /* If \n, also do \r */
    if (c == '\n')
        serial_putc ('\r');
}
serial_putc函数是直接和控制相关的,通过UTXH寄存器发送数据。
void fputc (int file, const char c)
{
    if (file < MAX_FILES)
        stdio_devices[file]->putc (c);
}
这是在console_init_r中设置stdio_devices[]后才有的,其他的是类似的。

1.2putc和fputc的关系
void putc (const char c)
{
#ifdef CONFIG_SILENT_CONSOLE
    if (gd->flags & GD_FLG_SILENT)
        return;
#endif

    if (gd->flags & GD_FLG_DEVINIT) {
        /* Send to the standard output */
        fputc (stdout, c);
    } else {
        /* Send directly to the handler */
        serial_putc (c);
    }
}
这是console_init_r中设置gd->flags & GD_FLG_DEVINIT,也就是串口设备完全初始化之后才有这种关系,其他的函数是类似的。

二、serial_printf (const char *fmt, ...)
serial_printf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用serial_puts函数将临时缓冲中的字符串数据打印到终端中去。
void serial_printf (const char *fmt, ...)
{
    va_list args;
    uint i;
    char printbuffer[CFG_PBSIZE];

    va_start (args, fmt);

    /* For this to work, printbuffer must be larger than
     * anything we ever want to print.
     */
    i = vsprintf (printbuffer, fmt, args);
    va_end (args);

    serial_puts (printbuffer);
}
三、fprintf(int file, const char *fmt, ...)
fprintf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用fputs函数将临时缓冲中的字符串数据打印到终端中去。
void fprintf (int file, const char *fmt, ...)
{
    va_list args;
    uint i;
    char printbuffer[CFG_PBSIZE];

    va_start (args, fmt);

    /* For this to work, printbuffer must be larger than
     * anything we ever want to print.
     */
    i = vsprintf (printbuffer, fmt, args);
    va_end (args);

    /* Send to desired file */
    fputs (file, printbuffer);
}
四、vprintf(const char *fmt, va_list args)
vprintf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用puts函数将临时缓冲中的字符串数据打印到终端中去。
void vprintf (const char *fmt, va_list args)
{
    uint i;
    char printbuffer[CFG_PBSIZE];

    /* For this to work, printbuffer must be larger than
     * anything we ever want to print.
     */
    i = vsprintf (printbuffer, fmt, args);

    /* Print the string */
    puts (printbuffer);
}
五、printf(const char *fmt, ...)
printf函数是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用puts函数将临时缓冲中的字符串数据打印到终端中去。
void printf (const char *fmt, ...)
{
    va_list args;
    uint i;
    char printbuffer[CFG_PBSIZE];

    va_start (args, fmt);

    /* For this to work, printbuffer must be larger than
     * anything we ever want to print.
     */
    i = vsprintf (printbuffer, fmt, args);
    va_end (args);

    /* Print the string */
    puts (printbuffer);
}
六、小结
serial_printf、vprintf和pringf函数基本相同,都是通过一个宏va_start把所有的可变参数放到了由args指向的一块内存中,vsprintf将变参列表args中的变量按照fmt中规定的格式保存到临时缓冲printbuffer中,最后调用不同的串口输出函数将临时缓冲中的字符串数据打印到终端中去。下面我们就来分析一下va_start、va_eng和vsprintf。
————————————————
版权声明:本文为CSDN博主「ce123」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ce123_zhouwei/article/details/7364294

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值