用户实现简单的printf函数,itoa,itox,并且用S5PV210进行实验

来源:互联网 发布:淘宝拆车变速箱 编辑:程序博客网 时间:2024/05/17 08:30

这个不是我原创的,是我老师写的,先写成博客,方便以后查看.大笑

运行环境是三星S5PV210开发板,然后,裸机编程的方式实现printf函数,不多说废话:

步骤一:

写汇编引导文件(很简单,就几行代码):

.global _start_start:bl mainloop:b loop

上面这几行代码主要是通过执行后,引导进入主函数,那么,之后就是我们熟知的C代码的编写了,

步骤二:

写自定义的printf函数(C语言):

#define GPA0CON (*(volatile unsigned long *)0xE0200000)#define ULCON0 (*(volatile unsigned long *)0xE2900000)#define UCON0 (*(volatile unsigned long *)0xE2900004)#define UTRSTAT0 (*(volatile unsigned long *)0xE2900010)#define UTXH0 (*(volatile unsigned long *)0xE2900020)#define URXH0 (*(volatile unsigned long *)0xE2900024)#define UBRDIV0 (*(volatile unsigned long *)0xE2900028)#define UDIVSLOT0 (*(volatile unsigned long *)0xE290002C)void uart_init(){//GPIO初始化GPA0CON &= ~0xff;GPA0CON |= 0x22;//uart设置传输格式//8bit,1s,none_checkULCON0 = 0x3;//设置读写模式UCON0 = 0x5;//设置波特率UBRDIV0 = 34;UDIVSLOT0 = 0xDFDD;}char _getc(){char ch;//查询是否有有效数据while((UTRSTAT0 & 0x1) == 0);ch = URXH0;return ch;}void _putc(char ch){while((UTRSTAT0 & (0x1 << 2)) == 0);UTXH0 = ch;}void _puts(char *str){while(*str != '\0'){_putc(*str);if(*str == '\n')_putc('\r');str++;}}//printf#include <stdarg.h>//itoa自定义实现void itoa(int num, char *buf){    int i;    if(num < 10){buf[0] = num + '0';buf[1] = '\0';return;    }    itoa(num / 10, buf);    for(i = 0; buf[i] != '\0'; i++);    buf[i] = num % 10;    buf[i+1] = '\0';    return;}//itoxvoid itox(int num, char *buf){    int i;    if(num < 16){    if(num < 10){    buf[0] = num + '0';    buf[1] = '\0';    }else{    buf[0] = num - 10 + 'a';    buf[1] = '\0';    }    return;    }    itox(num / 16, buf);    for(i = 0; buf[i] != '\0'; i++);    if(num % 16 < 10){    buf[i] = num % 16 + 'a';    buf[i+1] = '\0';    }else{    buf[i] = num % 6 - 10 + 'a';    buf[i+1] = '\0';    }    return;}int myprintf(const char *format,...){va_list list;va_start(list, format);int n;char *s;char buf[128];while(*format != '\0'){    if(*format == '%'){format++;switch(*format){    case 'd':    n = va_arg(list, int);    itoa(n, buf);    _puts(buf);    break;    case 'x':    n = va_arg(list, int);    itox(n, buf);    _puts(buf);    break;    case 'c':    n = va_arg(list, int);    _putc(n);    break;    case 's':    s = va_arg(list, char*);    _puts(s);    break;}format++;    }else{_putc(*format);if(*format == '\n')_putc('\r');format++;    }}va_end(list);return 0;}

代码如上,因为要上板实验,所以,一开始是对uart寄存器的初始化(想进一步了解的话,自己去翻技术手册),之后,就是一步一步的实现一个简单的printf的代码,当然为此还需实现自定义的itoa,itox函数,因为是逻辑跑,所以自己实现是必须的,然后,做完上述几步之后,就该写主函数的测试代码了,

步骤三:(主函数测试代码):

int main(){    uart_init();    _puts("hello girl\n");    _puts("hello world\n");    _puts("hello teacher\n");    _puts("hello friend\n");    _puts("hello linux\n");    myprintf("hello a = %d, c = %c, x = 0x%x, s = %s\n",99,'c',0x11,"hello girl");    char ch;    for(;;){    ch = _getc();    _putc('=');    _putc(ch);    }    return 0;}

接下来,基本上已经大功告成了,需要编译一下,然后,我这边老师是写了一个简单的makefile,所以,这里也沿用makefile,

步骤四:(编写makefile)

all:arm-none-linux-gnueabi-gcc -c start.S -o start.oarm-none-linux-gnueabi-gcc -c main.c -o main.oarm-none-linux-gnueabi-gcc -c uart.c -o uart.oarm-none-linux-gnueabi-ld -Ttext=0x40008000 start.o main.o uart.o -oarmarm-none-linux-gnueabi-objdump -d arm > arm.disarm-none-linux-gnueabi-objcopy -O binary arm arm.binclean:rm *.o *.bin

代码如上,用到了交叉编译器,想进一步了解的童鞋,自己百度吧,关键技术点都已经提供了,上板实验走起:


如上图是实验的结果,用的是超级终端,不过,因为要运行程序,还需要烧写一个uboot,细节就不多说了,百度都有偷笑

原创粉丝点击