经常有人包括我自己关心printf是如何通过串口打印数据的。
在IAR中:以FRDM_KL26的SC为例或者FRDM_KE02Z的Driver为例
Printf()->printk()->prink_putc()->out_char()->uart_putchar()函数
在printf.c文件中
int
printf (const char *fmt, …)
{
va_list ap;
int rvalue;
PRINTK_INFO info;
info.dest = DEST_CONSOLE;
info.func = &out_char;
/*
* Initialize the pointer to the variable length argument list.
*/
va_start(ap, fmt);
rvalue = printk(&info, fmt, ap);
/*
* Cleanup the variable length argument list.
*/
va_end(ap);
return rvalue;
}
接着调用printk()函数,在ptintk()函数里调用printk_putc()函数。
if (c != '\n')
{
printk_putc(c, &count, info);
}
else
{
printk_putc(0x0D /* CR */, &count, info);
printk_putc(0x0A /* LF */, &count, info);
}
/*
* By using 'continue', the next iteration of the loop
* is used, skipping the code that follows.
*/
continue;
}
printk_putc()函数定义如下:
static void
printk_putc (int c, int *count, PRINTK_INFO *info)
{
switch (info->dest)
{
case DEST_CONSOLE:
info->func((char)c);
break;
case DEST_STRING:
*(info->loc) = (unsigned char)c;
++(info->loc);
break;
default:
break;
}
*count += 1;
}
这样就会调用out_char()函数。
Out_char()函数调用的就是uart发送函数。
/**********************************************************/
void
out_char (char ch)
{
if (TERM_PORT_NUM == 0)
uart0_putchar(UART0_BASE_PTR, ch);
else if (TERM_PORT_NUM == 1)
uart_putchar(UART1_BASE_PTR, ch);
else
uart_putchar(UART2_BASE_PTR, ch);
}
顺便说一下printf中 info.dest = DEST_CONSOLE;这句话的作用,这条语句从printk_putc()函数可以看出,它决定着是否打印到console中,如果它的值为DEST_STRING那么会将printf打印的值放到loc参数中,实际使用中可以存到一个char型数组中。
typedef struct
{
int dest;
void (*func)(char);
char *loc;
} PRINTK_INFO;
!!!!
在C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.0\arm\src\lib\dlib中有printf.c定义:
int (printf)(const char _Restrict *fmt, …)
{ /* print formatted to stdout */
int ans;
va_list ap;
va_start(ap, fmt);
ans = _Printf(&_Prout, (void *)1, fmt, &ap _SECURE_PARAM(0));
va_end(ap);
return (ans);
}
_STD_END
这时默认会打印到IAR的terminal。在程序中只要将原来的printf函数实现注释掉即可。调用printf函数只需要添加stdio.h头文件即可。
可以参考:
https://community.freescale.com/docs/DOC-98502
在Keil中:
http://www.stmcu.org/module/forum/thread-598294-1-1.html 非常好!!
Printf->fpuc()->out_char()->uart_putchar()
位于io.c 中
/**********************************************************/
int fputc(int ch, FILE *f)
{
out_char((char)ch);
return 1;
}
void
out_char (char ch)
{
UART_PutChar(TERM_PORT, ch);
}
在MQX中: