11 orangepi裸板实现printf函数
来源:互联网 发布:java public class读法 编辑:程序博客网 时间:2024/05/21 10:25
uart工作原理
printf可变参数的获取原理
在uboot上,首先uart第0个控制器已经被uboot驱动好了. uart控制器负责数据的收发,我们只要把数据交给uart控制器发出,和从uart控制器里把数据取回来即可.
也就是我们只要找到相应的uart控制器的配置寄存器即可.
uart0的基地址0x01C28000
UART_RBR : uart0的数据接收寄存器 0x01c28000, 我们通过这个寄存器从uart控制器里把数据取回
UART_THR : uart0的数据发送寄存器 0x01c28000, 我们通过这个寄存器把要发出的数据交给uart控制器
//注意这两个寄存器地址一样, 怎么区分是接收/发送. 通过对寄存器的读操作或写操作
UART_LSR : uart0的状态寄存器 0x01c28014, 通过这个寄存器可以判断是否可以发出数据或有数据可取回
// 第6位为1表示, 发送器为空了,可以接着给数据来发送.
// 第0位为1表示uart控制器已接收到数据, 可以从控制器取回数据.
///////////////////////////////////////////////////
在uboot上测试:
mw.b 0x01c28000 0x41 1 //让uart0控制器发出'A'
///////////////
c代码测试:
实现putchar()功能函数
typedef volatile unsigned int u32; #define UART_RBR (*(u32 *)0x01c28000) #define UART_THR (*(u32 *)0x01c28000) #define UART_LSR (*(u32 *)0x01c28014) void putchar(int val); void _start() { int i; for (i = 0; i < 10; i++) { putchar('A'); putchar('B'); } } void putchar(int val) { while (!(UART_LSR & (1 << 6))) ; UART_THR = val; }
/////////////////
通过调用putchar函数实现puts函数:
typedef volatile unsigned int u32; #define UART_RBR (*(u32 *)0x01c28000) #define UART_THR (*(u32 *)0x01c28000) #define UART_LSR (*(u32 *)0x01c28014) void puts(char *line); void putchar(int val); void _start() { int i; for (i = 0; i < 10; i++) { puts("hello ...\n"); } } void putchar(int val) { while (!(UART_LSR & (1 << 6))) ; UART_THR = val; if ('\n' == val) putchar('\r'); } void puts(char *line) { while (*line) putchar(*line++); } //注意如程序里有使用数据段(包括只读数据段)的内容时,链接时需指定代码执行的地址. 而且程序也只能下载到指定的地址 arm-linux-gnueabihf-ld test.o -o test -Ttext=0x40008000
/////////////////////
实现printf函数
typedef volatile unsigned int u32; #define UART_RBR (*(u32 *)0x01c28000) #define UART_THR (*(u32 *)0x01c28000) #define UART_LSR (*(u32 *)0x01c28014) void puts(char *line); void putchar(int val); void printf(char *line, ...); void _start() { int i; puts("myprintf test ...\n"); printf("myprintf_int test %d\n", 112233); for (i = 0; i < 10; i++) { printf("myprintf test : %d, %c, %s, %x, %p\n", 1122, 'K', "hello", 0x77889394, 0x33445566); } } void print_int(int val) { // 12345678 if (val <= 0) return; print_int(val/10); putchar('0' + val%10); } void print_hex(int val) { if (val <= 0) return; print_hex(val/16); if ((val%16) >= 10) putchar('a' + val%16-10); else putchar('0' + val%16); } void printf(char *line, ...) { unsigned char *l = line; unsigned long *p = (unsigned long *)(&line); p++; while (*l) { while ((*l) && (*l != '%')) putchar(*l++); if (0 == *l) break; l++; switch (*l) { case 'd': print_int(*p++); break; case 'p': puts("0x"); case 'x': print_hex(*p++); break; case 'c': putchar(*p++); break; case 's': puts(*p++); break; } l++; } } void putchar(int val) { while (!(UART_LSR & (1 << 6))) ; UART_THR = val; if ('\n' == val) putchar('\r'); } void puts(char *line) { while (*line) putchar(*line++); }
阅读全文
0 0
- 11 orangepi裸板实现printf函数
- QT之涂鸦板实现
- 10 orangepi裸板控制IO
- linux和开发板实现信息共享
- android开发板实现关机功能
- printf函数
- printf()函数
- printf函数
- printf () 函数
- printf()函数
- printf函数
- printf函数
- 函数----printf
- printf函数
- printf()函数
- printf函数
- printf函数
- printf函数
- IntelliJ IDEA上创建maven Spring MVC项目
- PHP 正则匹配 HTML 标签
- Android的事件处理之基于监听的事件处理
- Eclipse反编译插件安装
- ClosedChannelException
- 11 orangepi裸板实现printf函数
- 简单的java缓存类实现
- 单例模式(Singleton Pattern)
- Java中的transient关键字
- 将在txt中的点数据批量arcgis插值后再输出为excel格式--未完
- iOS 动态调整tableViewCell 高度
- linux shell截取字符串方法
- 解决国产浏览器默认采用兼容模式的问题
- C# 图片压缩处理