作者:彭东林

邮箱:pengdonglin137@163.com

开发板:tiny4412ADK+S700 4GB Flash

主机:Wind7 64位

虚拟机:Vmware+Ubuntu12_04

u-boot:U-Boot 2010.12

Linux内核版本:linux-3.0.31

Android版本:android-4.1.2

我们以tiny4412为例分析串口驱动,下面我们从u-boot开始分析,然后再分析到Linux。

串口初始化

关于这部分代码流程参考件:tiny4412 u-boot 启动.pdf,这里主要分析函数:uart_asm_init

在初始化串口驱动之前已经进行了系统时钟以及内存的初始化。下面的代码取自board/samsung/tiny4412/lowlevel_init.S:

lowlevel_init:

          ……

         /* init system clock */

         bl      system_clock_init

         /* Memory initialize */

         bl      mem_ctrl_asm_init

         /* init uart for debug */

         bl      uart_asm_init

通过函数system_clock_init,得到如下结果:

APLL = 1400MHz, MPLL = 800MHz

通过函数uart_asm_init,将uart的波特率设置为了115200bps,下面是uart_asm_init的实现:

/*

 * uart_asm_init: Initialize UART in asm mode, 115200bps fixed.

 * void uart_asm_init(void)

 */

         .globl uart_asm_init

uart_asm_init:

         /* set GPIO to enable UART */

         @ GPIO setting for UART for UART0///

         ldr    r0, =0x11400000
ldr r1, =0x22222222
str r1, [r0]
ldr r0, =0x11400020
ldr r1, =0x222222
str r1, [r0] // tiny4412有4组uart aaarticlea/png;base64,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" alt="" /> // 设置uart0~4的时钟源为SCLKMPLL_USER_T,为800MHz
ldr r0, =S5PV310_CLOCK_BASE
ldr r1, =CLK_SRC_PERIL0_VAL
ldr r2, =CLK_SRC_PERIL0_OFFSET
str r1, [r0, r2] // 设置uart的分频系数为7,经计算得到SCLK UART=800M/(+)=100M ldr r1, =CLK_DIV_PERIL0_VAL
ldr r2, =CLK_DIV_PERIL0_OFFSET
str r1, [r0, r2] // 在tiny4412.h中定义了CONFIG_SERIAL0,即使用uart0作为默认的串口输出,所以S5PV310_UART_CONSOLE_BASE的值就是uart0控制器的基地址,为0x13800000,设置这个寄存的目的是启动并设置uart的FIFO功能,结果:启动uart0的FIFO功能,uart0的Rx FIFO Trigger Level是64B,Tx FIFO Trigger Level是32B ldr r0, =S5PV310_UART_CONSOLE_BASE
ldr r1, =0x111
str r1, [r0, #UFCON_OFFSET] // 设置uart0发送或者接受数据包每帧大小,这里设置为了8bit,1bit停止位,无奇偶校验,normal mode(除此之外还有一种叫做info-red的模式,用于红外发送和接受) mov r1, #0x3
str r1, [r0, #ULCON_OFFSET] // 设置uart0的读取接收缓冲区和写输出缓冲区的方式为中断或者轮询(除此之外还有DMA方式等);中断触发类型为电平触发 ldr r1, =0x3c5
str r1, [r0, #UCON_OFFSET] /* SCLK_UART0=100MHz, 波特率设置为115200 * 寄存器的值如下计算: * DIV_VAL = ,, / ( * ) - = . * UBRDIVn0 = 整数部分 = * UFRACVAL0 = 小数部分 x = . * = */ ldr r1, =UART_UBRDIV_VAL // 0x35
str r1, [r0, #UBRDIV_OFFSET]
ldr r1, =UART_UDIVSLOT_VAL // 0x4
str r1, [r0, #UDIVSLOT_OFFSET] // UTXH_OFFSET是输出缓冲区,这里是向uart0上打印 ‘O’ ldr r1, =0x4f4f4f4f
str r1, [r0, #UTXH_OFFSET] @'O'
mov pc, lr

上面完成了串口底层的初始化,接下来就可以使用了。下面以printf为例分析

u-boot中printf的实现

下面是u-boot中printf的源码

common/console.c

int printf(const char *fmt, ...)
{
va_list args;
uint i;
char printbuffer[CONFIG_SYS_PBSIZE]; // CONFIG_SYS_PBSIZE的值是256
va_start(args, fmt);
/* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/ i = vsprintf(printbuffer, fmt, args); // 将要打印的内容写到printbuffer中
va_end(args);
/* Print the string */
puts(printbuffer); // 将printbuffer中的内容从串口输出
return i;
} void puts(const char *s)
{
if (gd->flags & GD_FLG_DEVINIT) {
/* Send to the standard output */
fputs(stdout, s);
} else {
/* Send directly to the handler */
serial_puts(s);
}
}

common/serial.c

void serial_puts (const char *s)
{
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
dev->puts (s);
return;
}
serial_current->puts (s);
}

struct serial_device *default_serial_console(void) __attribute__((weak, alias("__default_serial_console")));

上面的意思是如果没有定义default_serial_console,那么就使用__default_serial_console

struct serial_device *__default_serial_console (void)
{
……
#if defined(CONFIG_SERIAL0)
return &s5p_serial0_device;
#elif defined(CONFIG_SERIAL1)
return &s5p_serial1_device;
#elif defined(CONFIG_SERIAL2)
return &s5p_serial2_device;
#elif defined(CONFIG_SERIAL3)
return &s5p_serial3_device;
#else
#error "CONFIG_SERIAL? missing."
#endif
……
}

由于我们使用的是uart0作为调试串口,并且定义了宏CONFIG_SERIAL0,所以__default_serial_console的返回值就是s5p_serial0_device的地址,下面我们看一下s5p_serial0_device

drivers/serial/serial_s5p.c

#define DECLARE_S5P_SERIAL_FUNCTIONS(port) \

int s5p_serial##port##_init(void) { return serial_init_dev(port); } \
void s5p_serial##port##_setbrg(void) { serial_setbrg_dev(port); } \
int s5p_serial##port##_getc(void) { return serial_getc_dev(port); } \
int s5p_serial##port##_tstc(void) { return serial_tstc_dev(port); } \
void s5p_serial##port##_putc(const char c) { serial_putc_dev(c, port); } \
void s5p_serial##port##_puts(const char *s) { serial_puts_dev(s, port); } #define INIT_S5P_SERIAL_STRUCTURE(port, name, bus) { \
name, \
bus, \
s5p_serial##port##_init, \
NULL, \
s5p_serial##port##_setbrg, \
s5p_serial##port##_getc, \
s5p_serial##port##_tstc, \
s5p_serial##port##_putc, \
s5p_serial##port##_puts, } DECLARE_S5P_SERIAL_FUNCTIONS(); struct serial_device s5p_serial0_device =
INIT_S5P_SERIAL_STRUCTURE(, "s5pser0", "S5PUART0");

综上,这里s5p_serial0_device的定义如下:

int s5p_serial0_init(void) { return serial_init_dev(); }
void s5p_serial0_setbrg(void) { serial_setbrg_dev(); }
int s5p_serial0_getc(void) { return serial_getc_dev(); }
int s5p_serial0_tstc(void) { return serial_tstc_dev(); }
void s5p_serial0_putc(const char c) { serial_putc_dev(c, ); }
void s5p_serial0_puts(const char *s) { serial_puts_dev(s, ); } struct serial_device s5p_serial0_device =
{
"s5pser0",
"S5PUART0",
s5p_serial0_init,
NULL,
s5p_serial0_setbrg,
s5p_serial0_getc,
s5p_serial0_tstc,
s5p_serial0_putc,
s5p_serial0_puts,
};

然后我们看一下它的puts函数指针:s5p_serial0_puts

void s5p_serial0_puts(const char *s) { serial_puts_dev(s, 0); }

然后分析serial_puts_dev(s, 0)

drivers/serial/serial_s5p.c:

void serial_puts_dev(const char *s, const int dev_index)
{
while (*s)
serial_putc_dev(*s++, dev_index);
} /*
* Output a single byte to the serial port.
*/ void serial_putc_dev(const char c, const int dev_index)
{
// 获得uart0的控制器基地址
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
// 读取发送状态寄存器,看是否有空余空间
/* wait for room in the tx FIFO */
while (!(readl(&uart->utrstat) & 0x2)) {
if (serial_err_check(dev_index, ))
return;
} // 将c中存放的字符写到发送缓冲区
writeb(c, &uart->utxh);
/* If \n, also do \r */
if (c == '\n')
serial_putc('\r');
}

下面是s5p_get_base_uart的实现

static inline struct s5p_uart *s5p_get_base_uart(int dev_index)
{
u32 offset = dev_index * sizeof(struct s5p_uart);
return (struct s5p_uart *)samsung_get_base_uart(); // 获得uart0控制器的基地址
}

include/asm/arch-exynos/cpu.h

#define SAMSUNG_BASE(device, base)                              \
static inline unsigned int samsung_get_base_##device(void) \
{ \
return S5PV310_##base; \
}
SAMSUNG_BASE(uart, UART_CONSOLE_BASE)
#define S5PV310_UART_CONSOLE_BASE (S5PV310_UART_BASE + S5PV310_UART0_OFFSET)

同理可以分析其他使用向串口读取或者写入数据的函数

tiny4412 串口驱动分析一 --- u-boot中的串口驱动的更多相关文章

  1. 利用 SPICE 分析理解心电图前端中的右腿驱动

      [导读] 心电图(ECG)学是一门将心脏离子去极(ionic depolarization) 后转换为分析用可测量电信号的科学.模拟电子接口到电极/患者设计中最为常见的难题之一便是优化右腿驱动 ( ...

  2. linux驱动基础系列--Linux下Spi接口Wifi驱动分析

    前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...

  3. tiny4412 串口驱动分析七 --- log打印的几个阶段之内核启动阶段(earlyprintk)

    作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...

  4. tiny4412 串口驱动分析四 --- 修改默认的串口输出

    作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...

  5. tiny4412 串口驱动分析六 --- TTY驱动架构

    转载: http://www.linuxidc.com/Linux/2013-11/92639.htm 参考: http://blog.csdn.net/lamdoc/article/details/ ...

  6. linux的串口驱动分析

    1.串口驱动中的数据结构 • UART驱动程序结构:struct uart_driver  驱动 • UART端口结构: struct uart_port  串口 • UART相关操作函数结构: st ...

  7. linux串口驱动分析——发送数据

    一.应用程序中write函数到底层驱动历程 和前文提到的一样,首先先注册串口,使用uart_register_driver函数,依次分别为tty_register_driver,cdev_init函数 ...

  8. linux串口驱动分析

    linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作 ...

  9. Linux 串口、usb转串口驱动分析(2-2) 【转】

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4186852 Linux 串口.usb转 ...

随机推荐

  1. 阻塞&&非阻塞

    读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回.但是从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调 ...

  2. class内部处理

    class A { public: int foo( ) { return val ; } static int staFun( ) { return staVal ; } static int st ...

  3. nf_register_hooks解读

    nf_register_hooks是什么 net->netns_nf->nf_hook_entry[NFPROTO_NUMPROTO][NF_MAX_HOOKS=8] (nf)       ...

  4. 【bzoj1927】[Sdoi2010]星际竞速 有上下界费用流

    原文地址:http://www.cnblogs.com/GXZlegend/p/6832464.html 题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军 ...

  5. 【转】去掉HTML5中number类型input字段的小箭头

    第一种方案: 在chrome下: input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{    -webkit-appea ...

  6. tcp nio 远程主机强迫关闭了一个现有的连接

    import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import ...

  7. shell面试经典70例

    转载自:http://www.imooc.com/article/1131 1) 如何向脚本传递参数 ? ./script argument 例子: 显示文件名称脚本 ./show.sh file1. ...

  8. HDU1536&&POJ2960 S-Nim(SG函数博弈)

    S-Nim Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status ...

  9. android hook 框架 xposed 如何实现挂钩

    Android so注入-libinject2 简介.编译.运行 Android so注入-libinject2  如何实现so注入 Android so注入-Libinject 如何实现so注入 A ...

  10. 动态符号链接的细节 与 linux程序的加载过程

    转: http://hi.baidu.com/clivestudio/item/4341015363058d3d32e0a952 值得玩味的一篇分析程序链接.装载.动态链接细节的好文档 导读: by ...