一、应用程序中write函数到底层驱动历程

和前文提到的一样,首先先注册串口,使用uart_register_driver函数,依次分别为tty_register_driver,cdev_init函数,找到使用的file_operations,即应用程序与tty架构的统一接口。步骤不再赘述。

static const struct file_operations tty_fops ={

.llseek=no_llseek,

.read=tty_read,

.write=tty_write,

.poll=tty_poll,

.unlocked_ioctl=tty_ioctl,

.compat_ioctl=tty_compat_ioctl,

.open=tty_open,

.release=tty_release,

.fasync=tty_fasync,

};

tty_write函数

static ssize_t tty_write(struct file *file, const char __user *buf,

size_t count, loff_t*ppos)

{struct inode *inode = file->f_path.dentry->d_inode;struct tty_struct *tty =file_tty(file);struct tty_ldisc *ld;

ssize_t ret;

...

ret= do_tty_write(ld->ops->write, tty, file, buf, count);

...

}

这里通过do_tty_write函数调用到了线路规程(ldisc)中的函数,结构名为tty_ldisc_N_TTY。

struct tty_ldisc_ops tty_ldisc_N_TTY ={

.magic=TTY_LDISC_MAGIC,

.name= "n_tty",

.open=n_tty_open,

.close=n_tty_close,

.flush_buffer=n_tty_flush_buffer,

.chars_in_buffer=n_tty_chars_in_buffer,

.read=n_tty_read,

.write=n_tty_write,

.ioctl=n_tty_ioctl,

.set_termios=n_tty_set_termios,

.poll=n_tty_poll,

.receive_buf=n_tty_receive_buf,

.write_wakeup=n_tty_write_wakeup

};

n_tty_write函数

static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,const unsigned char *buf, size_t nr)

{const unsigned char *b =buf;

DECLARE_WAITQUEUE(wait, current);intc;

ssize_t retval= 0;

...

c = tty->ops->write(tty, b, nr);

...

}

ops为struct tty_operations类型,由上文可知该结构名为

static const struct tty_operations uart_ops ={

....write=uart_write,

...};

uart_write函数

static int uart_write(struct tty_struct *tty,const unsigned char *buf, intcount)

{struct uart_state *state = tty->driver_data;struct uart_port *port;struct circ_buf *circ;

unsignedlongflags;int c, ret = 0;

...

uart_start(tty);

...

}

uart_start函数中又调用了__uart_start函数

static void __uart_start(struct tty_struct *tty)

{struct uart_state *state = tty->driver_data;struct uart_port *port = state->uart_port;if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&

!tty->stopped && !tty->hw_stopped)

port->ops->start_tx(port);

}

这里的port就是uart_port类型的了,终于到达底层驱动了,好累。。又是这个数组,同样的函数操作集

static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] ={

[0] ={

.port={

.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),

.iotype=UPIO_MEM,

.irq=IRQ_S3CUART_RX0,

.uartclk= 0,

.fifosize= 16,

.ops= &s3c24xx_serial_ops,

.flags=UPF_BOOT_AUTOCONF,

.line= 0,

}

},

...

}

所以在底层驱动与之对应的就是s3c24xx_serial_start_tx这个函数。层层追溯下来,最终与应用程序中的write函数千里相会。。。

static void s3c24xx_serial_start_tx(struct uart_port *port)

{struct s3c24xx_uart_port *ourport =to_ourport(port);if (!tx_enabled(port)) {if (port->flags &UPF_CONS_FLOW)

s3c24xx_serial_rx_disable(port);

enable_irq(ourport->tx_irq);

tx_enabled(port)= 1;

}

}

但是要让各位看官失望了。这个函数很简单,功能上来说就是如果没有打开发送使能就去打开。那么串口驱动又是在什么地方去完成发送数据相关的操作呢?

预知后事如何,且听下回分析。

如果有疑问或建议,欢迎指出。

原文:http://www.cnblogs.com/51qianrushi/p/4324845.html

linux串口发送数据程序,linux串口驱动分析——发送数据相关推荐

  1. 深入学习Linux摄像头(三)虚拟摄像头驱动分析

    深入学习Linux摄像头系列 深入学习Linux摄像头(一)v4l2应用编程 深入学习Linux摄像头(二)v4l2驱动框架 深入学习Linux摄像头(三)虚拟摄像头驱动分析 深入学习Linux摄像头 ...

  2. 2020互联网数据分析师教程视频 统计学分析与数据实战 r语言数据分析实战 python数据分析实战 excel自动化报表分析实战 excel数据分析处理实战

    2020互联网数据分析师教程视频 统计学分析与数据实战 r语言数据分析实战 python数据分析实战 excel自动化报表分析实战 excel数据分析处理实战

  3. linux如何运行java程序,Linux环境下运行简单java程序

    一.安装java 1.下载jdk8 选择对应jdk版本下载.(Tips:可在Windows下载完成后,通过FTP或者SSH到发送到Linux上) 2. 登录Linux,切换到root用户 su roo ...

  4. USB总线-Linux内核USB3.0设备控制器之UDC驱动分析(六)

    1.概述 UDC驱动的接口都定义在drivers/usb/gadget/udc/core.c文件中.USB Function驱动通过调用这些接口匹配及访问USB设备控制器,而底层USB控制器驱动要实现 ...

  5. 怎么用linux设计一个小程序,“Linux”小程序发布一个月后,我们发现了什么

    原标题:"Linux"小程序发布一个月后,我们发现了什么 这一个月来,这个小程序得到了八千多人的使用,一百多位贡献者实际参与了翻译贡献,其中贡献最高的"Datura st ...

  6. linux如何调试elf程序,Linux应用程序elf描述

    玩Linux的人应该明白ELF文件是一种文件格式,就好比.txt,.doc等一样,只是这个文件是按照特定信息排列组成,同样在windows上也存在一种格式,它叫PE,老的叫dos.下面我就来看看ELF ...

  7. linux序列比对程序,Linux程序管理:top.htop.glances,dstat等命令使用方法

    什么是进程? 在Linux系统中:触发任何一个事件时,系统都会将它定义为一个进程,并且给予这个进程一个ID,称为PID,同时依据触发这个进程的用户与相关属性,给予这个PID一组有效的全乡设置.而程序就 ...

  8. Linux keypad 设备树,matrix_keypad 矩阵按键驱动分析

    matrix_keypad 矩阵按键驱动分析 //主要函数调用过程 matrix_keypad_probe matrix_keypad_parse_dt //根据设备树构造 pdata pdata-& ...

  9. 蓝牙串口通信java_Java程序与串口通信的实现及通信原码-全网最详细,一步一步教会...

    RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准.RS-422(EIA RS-422-AStandard)是Apple的Macintosh计算机的串口连接标准.RS ...

  10. linux文件操作函数程序,linux 文件操作函数

    文件操作(Linux) 常用linux函数库中的基本函数 1. close函数,关闭文件 2. creat函数,建立文件 3. dup.dup2函数,复制文件描述词 4. fcntl函数,文件描述词操 ...

最新文章

  1. LeetCode Decode Ways
  2. 【Android 逆向】类加载器 ClassLoader ( 使用 DexClassLoader 动态加载字节码文件 | 准备 DEX 字节码文件 )
  3. UA MATH563 概率论的数学基础 鞅论初步1 条件期望
  4. 群晖 设置 php 服务器,群晖NAS服务器iSCSI管理器配置连接及使用说明
  5. Kubernetes架构为什么是这样的?
  6. was 程序jvm_【保家护行航】WAS知识学习分享
  7. 《go 语言程序设计》读书笔记(六)Goroutine与系统线程的区别
  8. js模板引擎 之handlebars.js
  9. JAVA8的双重循环怎么优化_Java8处理List的双层循环问题代码实例
  10. C#调用API函数EnumWindows枚举窗口的方法
  11. “CEPH浅析”系列之六——CEPH与OPENSTACK
  12. PcShare 2005 源代码
  13. 数字化大时代崛起的数据安全能力框架
  14. “无法访问 您可能没有权限使用网络资源”解决办法
  15. 重磅丨深度解读UN报告:AI新技术革命将如何重塑就业和全球化格局?
  16. 手机免流量,还会是天方夜谭吗?
  17. 华为路由器负载均衡_华为OSPF路由负载分担配置示例
  18. Kali安装天使之剑AngelSword,python3的poc!!
  19. Rikka with Travels【换根树dp】
  20. 架构师小跟班:推荐46个非常经典的Linux面试题

热门文章

  1. klee2.3 安装教程1-2
  2. 关于OpenGL编程指南第一个程序出错的问题
  3. Qt 使用 MPV 开源播放器
  4. Qt显示pdf系列2——QAxWidget打开Office文件及pdf
  5. 再论WGS84、ITRF2008及NavCom StarFire
  6. 自适应粒子群优化算法的MATLAB性能仿真
  7. Java常用设计模式详解及其优缺点
  8. ly_Python总结之三:初为程序员的感悟
  9. Windows10虚拟机上的spark环境搭建
  10. 云端Python编程给你“好看”