1、串口驱动中的数据结构

• UART驱动程序结构:struct uart_driver  驱动

• UART端口结构: struct uart_port  串口

• UART相关操作函数结构: struct uart_ops   串口操作函数集

• UART状态结构: struct uart_state 串口状态

• UART信息结构: struct uart_info  串口信息

2、串口驱动程序-初始化

3、串口驱动分析-打开设备

static int s3c24xx_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
port->mapbase, port->membase); rx_enabled(port) = ; ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, ,
s3c24xx_serial_portname(port), ourport); if (ret != ) {
printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
return ret;
} ourport->rx_claimed = ; dbg("requesting tx irq...\n"); tx_enabled(port) = ; ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, ,
s3c24xx_serial_portname(port), ourport); if (ret) {
printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq);
goto err;
} ourport->tx_claimed = ; dbg("s3c24xx_serial_startup ok\n"); /* the port reset code should have done the correct
* register setup for the port controls */ return ret; err:
s3c24xx_serial_shutdown(port);
return ret;
}

3、串口驱动程序-数据发送

static void s3c24xx_serial_start_tx(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
static int a =;//temp
if (port->line == ) {
// printk("485_start_tx\n"); if(a){
s3c_gpio_cfgpin(S3C64XX_GPK(), S3C_GPIO_SFN());
a=;
}
gpio_set_value(S3C64XX_GPK(), );
}
if (!tx_enabled(port)) {
if (port->flags & UPF_CONS_FLOW)
s3c24xx_serial_rx_disable(port); enable_irq(ourport->tx_irq);
tx_enabled(port) = ;
}
}
static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
{
struct s3c24xx_uart_port *ourport = id;
struct uart_port *port = &ourport->port;
struct circ_buf *xmit = &port->state->xmit;
int count = ; if (port->x_char) {
wr_regb(port, S3C2410_UTXH, port->x_char);
port->icount.tx++;
port->x_char = ;
goto out;
} /* if there isn't anything more to transmit, or the uart is now
* stopped, disable the uart and exit
*/ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
s3c24xx_serial_stop_tx(port);
goto out;
} /* try and drain the buffer... */ while (!uart_circ_empty(xmit) && count-- > ) {
if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
break; wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail + ) & (UART_XMIT_SIZE - );
port->icount.tx++;
} if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port); if (uart_circ_empty(xmit))
s3c24xx_serial_stop_tx(port); out:
return IRQ_HANDLED;
}

4、串口驱动程序-数据接收

s3c24xx_serial_rx_chars(int irq, void *dev_id)
{
struct s3c24xx_uart_port *ourport = dev_id;
struct uart_port *port = &ourport->port;
struct tty_struct *tty = port->state->port.tty;
unsigned int ufcon, ch, flag, ufstat, uerstat;
int max_count = ; while (max_count-- > ) {
ufcon = rd_regl(port, S3C2410_UFCON);
ufstat = rd_regl(port, S3C2410_UFSTAT); if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == )
break; uerstat = rd_regl(port, S3C2410_UERSTAT);
ch = rd_regb(port, S3C2410_URXH); if (port->flags & UPF_CONS_FLOW) {
int txe = s3c24xx_serial_txempty_nofifo(port); if (rx_enabled(port)) {
if (!txe) {
rx_enabled(port) = ;
continue;
}
} else {
if (txe) {
ufcon |= S3C2410_UFCON_RESETRX;
wr_regl(port, S3C2410_UFCON, ufcon);
rx_enabled(port) = ;
goto out;
}
continue;
}
} /* insert the character into the buffer */ flag = TTY_NORMAL;
port->icount.rx++; if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",
ch, uerstat); /* check for break */
if (uerstat & S3C2410_UERSTAT_BREAK) {
dbg("break!\n");
port->icount.brk++;
if (uart_handle_break(port))
goto ignore_char;
} if (uerstat & S3C2410_UERSTAT_FRAME)
port->icount.frame++;
if (uerstat & S3C2410_UERSTAT_OVERRUN)
port->icount.overrun++; uerstat &= port->read_status_mask; if (uerstat & S3C2410_UERSTAT_BREAK)
flag = TTY_BREAK;
else if (uerstat & S3C2410_UERSTAT_PARITY)
flag = TTY_PARITY;
else if (uerstat & (S3C2410_UERSTAT_FRAME |
S3C2410_UERSTAT_OVERRUN))
flag = TTY_FRAME;
} if (uart_handle_sysrq_char(port, ch))
goto ignore_char; uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN,
ch, flag); ignore_char:
continue;
}
tty_flip_buffer_push(tty); out:
return IRQ_HANDLED;
}

附:linux系统中一般的流控技术

linux的串口驱动分析的更多相关文章

  1. linux串口驱动分析

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

  2. linux UART串口驱动开发文档

    转:http://www.360doc.com/content/10/0417/18/829197_23519037.shtml linux UART串口驱动开发文档时间:2010-01-09 14: ...

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

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

  4. linux串口驱动分析——打开设备

    串口驱动是由tty_driver架构实现的.一个应用程序中的函数要操作硬件,首先会经过tty,级级调用之后才会到达驱动之中.本文先介绍应用程序中打开设备的open函数的整个历程. 首先在串口初始化中会 ...

  5. linux串口驱动分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/11946591 硬件资源及描述 s3c2440A 通用异步接收器和发送器(UART)提供了 ...

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

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

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

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

  8. tiny4412 串口驱动分析一 --- u-boot中的串口驱动

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

  9. (linux)MMC 卡驱动分析

    最近花时间研究了一下 MMC 卡驱动程序,开始在网上找了很多关于 MMC 卡驱动的分析文章,但大都是在描述各个层,这对于初学者来讲帮助并不大,所以我就打算把自己的理解写下来,希望对大家有用.个人觉得理 ...

随机推荐

  1. 十步让你调试mvc源码

    1.下载 mvc 当前版本的源码,地址:http://aspnetwebstack.codeplex.com/SourceControl/latest 2.编译源码,参考:http://www.cnb ...

  2. that-annoying-insert-problem-getting-data-into-the-db-using-dapper

    http://samsaffron.com/archive/2012/01/16/that-annoying-insert-problem-getting-data-into-the-db-using ...

  3. <%%>与<%#%>与<%=%>

    在asp.net中经常出现包含这种形式<%%>的html代码,总的来说包含下面这样几种格式: 一. <%%> 这种格式实际上就是和asp的用法一样的,只是asp中里面是vbsc ...

  4. Redis数据持久化之RDB持久化

    因为Redis服务器将数据存储在内存里面,而一旦服务器被关闭或者运行服务器的主机本身被关闭的话,存储在内存里面的数据就会消失不见: 如果我们仅仅是将redis用作缓存的话,那么这种数据丢失带来的问题并 ...

  5. 【OpenCV入门教程之三】 图像的载入,显示和输出 一站式完全解析(转)

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/20537737 作者:毛星云(浅墨)  ...

  6. 学习总结 JAVA环境配置 及其相应的步骤

    相应的操作步骤 第一步: 右键我的电脑→属性→高级系统设置→环境变量→打开环境变量 第二步:在系统变量中添加JAVA_HOME ,并引用到相对应的地址. 第三步:在系统变量 path 中最前端(按ho ...

  7. telnet localhost 8089 ==》》命令使用

    GET /ccc/abc.html HTTP/1.1 host:localhost     客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式, HTTP协议用于定 ...

  8. jquery selector 使用方法

    <select class="selector"></select> 1 设置value为pxx的项选中 $(".selector"). ...

  9. SQL server 时间处理自连接

     --延时的订单select t1.OrderId order1, t1.VerifyStatusId id1,t1.VerifyDate '时间1', t2.OrderId order2, t2.V ...

  10. C++ 牛人博客(不断更新中...)

    http://www.zhangjiee.com/ 新浪微博@独酌逸醉. Github. GitCafe. stackoverflow. Quora http://cpp1x.org/ 刘未鹏 | M ...