一、 現在串口只能列印字串,沒有實現格式化輸出的功能,所以變數的值還不能列印出來。"逐行列印技術"沒法實施,這太痛苦了,馬上加入printf。 二、代碼 root@ubuntu:~/myboot# tree . ├── main.c ├── Makefile ├── nand.c ├── nand.h ├── sdram.c ├── start.S ├── uart.c ├── uart.h ├── u-boot.lds └── vsprintf.c 0 directories, 10 files 2.1 uart.c 加入uart_printf的實現
點擊(此處)摺疊或開啟 #include
#define GPHCON (* (volatile unsigned int *) 0x56000070)
#define GPHUP (* (volatile unsigned int *) 0x56000078)
#define ULCON0 (* (volatile unsigned int *) 0x50000000)
#define UCON0 (* (volatile unsigned int *) 0x50000004)
#define UFCON0 (* (volatile unsigned int *) 0x50000008)
#define UMCON0 (* (volatile unsigned int *) 0x5000000C)
#define UTRSTAT0 (* (volatile unsigned int *) 0x50000010)
#define UERSTAT0 (* (volatile unsigned int *) 0x50000014)
#define UFSTAT0 (* (volatile unsigned int *) 0x50000018)
#define UMSTAT0 (* (volatile unsigned int *) 0x5000001C)
#define UTXH0 (* (volatile unsigned char *) 0x50000020) //類型為:char* #define URXH0 (* (volatile unsigned char *) 0x50000024)
#define UBRDIV0 (* (volatile unsigned int *) 0x50000028)
#define BAUD_RATE 115200
void uart_init(void) {
GPHCON = 0x000000A0;
GPHUP = 0x000007FF;
ULCON0 = (0x03); //8N1
UCON0 = (0x01<<2)|(0x01);
UFCON0 = 0;
UMCON0 = 0;
UBRDIV0 = (int)((50*1000*1000)/(BAUD_RATE*16))-1;
}
unsigned char uart_getc(void)
{
while(!(UTRSTAT0 & 0x01))
;
return (URXH0 & 0xff);
}
void uart_putc(char c)
{
while (!(UTRSTAT0&0x02))
;
UTXH0 = c;
if('\n' == c)
uart_putc('\r');
}
void uart_puts(char *s)
{
while (*s)
{
uart_putc(*s++);
}
}
/*uart_printf*/ void uart_printf(char *fmt, ...)
{
va_list ap;
char buf[256];
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
uart_puts(buf);
va_end(ap);
} 2.2 vsprintf.c 從linux_0.11 copy過來,稍做修改
點擊(此處)摺疊或開啟 #include <stdarg.h>
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
int strlen(const char *s)
{
const char *sc;
for(sc=s; *sc!='\0'; ++sc)
;
return (sc-s);
}
static int skip_atoi(const char **s)
{
int i=0;
while (is_digit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */
#if 0
#define do_div(n,base) ({ \
int __res; \
__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \
__res; })
#endif
#define do_div(n,base) ({ \
int __res; \
__res = ((unsigned long) n) % (unsigned) base; \
n = ((unsigned long) n) / (unsigned) base; \
__res; \
})
static char * number(char * str, int num, int base, int size, int precision
,int type)
{
char c,sign,tmp[36];
const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz";
if (type&LEFT) type &= ~ZEROPAD;
if (base<2 || base>36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ' ;
if (type&SIGN && num<0) {
sign='-';
num = -num;
} else
sign=