2. 串口标准输入输出
要想在Bootloader中使用scanf()和print()并不容易,因为不能直接使用C库函数。scanf()要从串口获得输入, print()要向串口进行输出。必须自己实现常用的C库函数, 不仅包括输入输出函数,还包括字符串操作函数如strcmp(), strcpy()等。幸好在《嵌入式Linux应用开发完全手册》这本书的源代码中提供了这样简化的C库,所以就直接拿来用了。
代码中定义了两个全局数组作为输入输出缓冲区:
static unsigned char g_pcOutBuf[ 1024 ];
static unsigned char g_pcInBuf[ 1024 ];
其实我们可以把这两个缓冲区定位在CPU的 SteppingStone 里面,这样可以节省2K的空间。
scanf()的实现里面调用 getc() 函数, printf() 的实现里面调用 putc() 函数。我们自己写getc()函数为从串口读取字符, putc()函数实现为向串口发送字符, 这样标准输入输出就跟串口联系在一起了。
/* 发送一个字符 */
void putc(unsigned char c)
{
/* 等待,直到发送缓冲区中的数据已经全部发送出去 */
while (!(UTRSTAT0 & TXD0READY));
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
UTXH0 = c;
}
/* 接收字符 */
unsigned char getc(void)
{
unsigned char ret;
/* 等待,直到接收缓冲区中的有数据 */
while(!(UTRSTAT0 & RXD0READY));
/* 直接读取URXH0寄存器,即可获得接收到的数据 */
ret = URXH0;
if (ret == 0x0d || ret == 0x0a)
{
putc(0x0d);
putc(0x0a);
}
else
{
putc(ret);
}
return ret;
}
void putc(unsigned char c)
{
/* 等待,直到发送缓冲区中的数据已经全部发送出去 */
while (!(UTRSTAT0 & TXD0READY));
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
UTXH0 = c;
}
/* 接收字符 */
unsigned char getc(void)
{
unsigned char ret;
/* 等待,直到接收缓冲区中的有数据 */
while(!(UTRSTAT0 & RXD0READY));
/* 直接读取URXH0寄存器,即可获得接收到的数据 */
ret = URXH0;
if (ret == 0x0d || ret == 0x0a)
{
putc(0x0d);
putc(0x0a);
}
else
{
putc(ret);
}
return ret;
}