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. No data in the view dba_hist_undostat (文档 ID 1558157.1)

    APPLIES TO: Oracle Database - Enterprise Edition - Version 10.2.0.1 to 11.2.0.3 [Release 10.2 to 11. ...

  2. Centos 时间同步服务器

    From: http://www.iteye.com/topic/599648 中国国家授时中心: http://www.time.ac.cn/stime.asp 其他网络时间服务器地址如下:(也可以 ...

  3. python基础set

    1.set set是一个无序的不重复的集合 li=[11,22,33,11] s=set(li) print(s) {11,22,33}  set提供的方法 1.add(self, *args, ** ...

  4. url 参数的加号变成空格处理

    今天在调试客户端向服务器传递参数时,参数中的“+”全部变成了空格,原因是URL中默认的将“+”号转义了. 解决方法如下: 方法一.修改客户端 将客户端带“+”的参数中的“+”全部替换为‍“2B%”,这 ...

  5. hive添加分区

    添加分区 alter table 表名 add partition (dt='2016-09-12'); select * from 表名 where dt = '2016-09-12' limit ...

  6. vsftp.conf

    anonymous_enable=NO local_enable=YES write_enable=YES dirmessage_enable=YES xferlog_enable=YES xferl ...

  7. 使用POI导入Excel异常Cannot get a text value from a numeric cell 解决

    POI操作Excel时因为Excel数据Cell有不同的类型,会出现Cannot get a text value from a numeric cell的异常错误. 异常原因:Excel数据Cell ...

  8. 生成Excel直接以流或字节形式发给客户端,无需在服务生成一个实体文件。

    public ActionResult ExportAgentBooking(string Company_Id, string Company_Name)//Altman.Web.BCDAdmin. ...

  9. 洛谷P2738 [USACO4.1]篱笆回路Fence Loops

    P2738 [USACO4.1]篱笆回路Fence Loops 11通过 21提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 ...

  10. FindResource函数错误代码:1813-找不到映像文件中指定的资源类型 与LoadResource函数错误代码:1812-指定的映像文件不包含资源区域

    HRSRC WINAPI FindResource( _In_opt_  HMODULE hModule, _In_      LPCTSTR lpName, _In_      LPCTSTR lp ...