Linux串口驱动程序(4)-数据发送

2023-05-16

1.tty数据发送调用关系

  • 怎么样才能找到发送数据所使用的函数呢?打开uart_register_driver函数,找到里面的tty_register_driver,转到定义,这里调用了tty_fops这个结构,这几结构里就保存了读写串口的函数tty_write:
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,
};
  • ty_write的函数又调用n_tty_write函数来实现,n_tty_write又调用uart_write函数,最终找到串口驱动程序中的s3c24xx_serial_start_tx,来实现串口的方式数据。
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;
	}
}
  • 分析这段代码可知知道,这里做的工作是判断串口是否打开,如果没有打开,这把它打开并使能中断。这里面并没有哪些代码时实现数据发送的,那数据是在哪里发送的呢?其实是在中断函数s3c24xx_serial_tx_chars里面发送数据的!
  • 在分析发送函数之还需要介绍一下循环缓冲,循环缓冲存放的就是需要发送的数据,中断程序s3c24xx_serial_tx_chars拿到循环缓冲里的数据,然后把它发送出去,那循环缓冲的数据又是什么时候写进去的呢?其实是在调用uart_write的时候写进去的。总结一下,发送流程如下:
  • 应用程序调用write->tty_write->(线路规程当中)n_tty_write->(struct tty_operations uart_ops)uart_write->uart_start->__uart_start->(struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] .ops->s3c24xx_serial_ops)->s3c244xx_serial_start_tx(打开中断)->s3c24xx_serial_tx_chars(发送数据)。
  • 接下来分析s3c24xx_serial_tx_chars。

2.串口发送函数分析

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 = 256;
 
	// 判断x_char里面是否有数据,如果有数据把它发送然后退出
        if (port->x_char) {
		wr_regb(port, S3C2410_UTXH, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		goto out;
	}
 
	/* if there isnt 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-- > 0) {
		if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
			break;
 
		wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);  // 从循环缓冲的尾部去除数据,写入S3C2410_UTXH
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);  // 调整循环缓冲的位置
		port->icount.tx++;
	}
 
	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);   // 循环缓冲里面的数据小于WAKEUP_CHARS(256),则唤醒之前阻塞的发送进程
 
	if (uart_circ_empty(xmit))
		s3c24xx_serial_stop_tx(port);   // 如果循环缓冲为空了,把发送中断关闭
 
 out:
	return IRQ_HANDLED;
}
  • 分析代码可知:
    • 1、判断x_char里面是否有数据,如果有数据把它发送然后退出。
    • 2、判断循环缓冲是否为空,或者串口不允许发送,则把中断关闭
    • 3、利用while循环发送数据,这里面循环的条件是:1循环缓冲不为空,2发送的数据量最多为256字节。然后读取S3C2410_UFSTAT(第14位),判断发送的fifo是否满了,如果(为1)满了要退出,没有满就从循环缓冲的尾部去除数据,写入S3C2410_UTXH。然后调整循环缓冲的位置。
    • 4、最后完成扫尾工作,如果循环缓冲里面的数据小于WAKEUP_CHARS(256),则唤醒之前阻塞的发送进程,同时如果循环缓冲为空了,把发送中断关闭。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux串口驱动程序(4)-数据发送 的相关文章

  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • 如何修复“iptables:没有该名称的链/目标/匹配”?

    我在我的 Linux 嵌入式系统上构建并安装了 iptables 如果我列出所有规则 则一切正常 iptables list Chain INPUT policy ACCEPT target prot opt source destinat
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • 抑制 makefile 中命令调用的回显?

    我为一个作业编写了一个程序 该程序应该将其输出打印到标准输出 分配规范需要创建一个 Makefile 当调用它时make run gt outputFile应该运行该程序并将输出写入一个文件 该文件的 SHA1 指纹与规范中给出的指纹相同
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • 从 csv 文件中删除特定列,保持输出上的相同结构[重复]

    这个问题在这里已经有答案了 我想删除第 3 列并在输出文件中保留相同的结构 输入文件 12 10 10 10 10 1 12 23 1 45 6 7 11 2 33 45 1 2 1 2 34 5 6 I tried awk F 3 fil
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 为什么 Linux perf 使用事件 l1d.replacement 来处理 x86 上的“L1 dcache misses”?

    在英特尔 x86 上 Linux用途 https stackoverflow com a 52172985 149138事件l1d replacements来实施其L1 dcache load misses event 该事件定义如下 计数
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • Linux中的定时器类

    我需要一个计时器来以相对较低的分辨率执行回调 在 Linux 中实现此类 C 计时器类的最佳方法是什么 有我可以使用的库吗 如果您在框架 Glib Qt Wx 内编写 那么您已经拥有一个具有定时回调功能的事件循环 我认为情况并非如此 如果您
  • sendfile64 只复制约2GB

    我需要使用 sendfile64 复制大约 16GB 的文件 到目前为止我所取得的成就是 include
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im

随机推荐

  • 人工智能会取代程序员吗?

    多亏了人工智能 xff08 AI xff09 xff0c 软件将在未来自行编写 至少 xff0c 这就是谷歌首席执行官桑达尔 皮查伊 xff08 Sundar Pichai xff09 对软件开发未来的看法 他是对的 xff01 这并不能使
  • 人工智能和5G在无人机技术中的作用

    技术为我们提供了许多引人入胜的设备和发明 xff0c 无人机就是其中之一 无人机 xff0c 在技术术语中也称为无人机 xff08 UAV xff09 xff0c 自2007年首次出现以来越来越受欢迎 这些小工具最初是手动和远程控制的 无人
  • 惠普暗影精灵笔记本开机自动打开小键盘,冷热启动均支持

  • STM32F4 使用结构体配置功能

    1 IIC配置 void IIC Mode Config void I2C InitTypeDef I2C InitStructure I2C InitStructure I2C Mode 61 I2C Mode I2C IIC模式 I2C
  • 执行 sudo apt-get update 报错:仓库 xxx 没有release文件 / 不再含有release文件

    输入命令 sudo apt get update 报错 这里可以看到有两个问题 xff0c 一个是 ubuntu自己的源连不上了 第二三个红框框 xff0c 一个是 vmware 这个软件 第一个红框框 首先解决第一个问题 archive
  • C++ 发送HTTP请求

    HTTPRequest HTTPRequest是一个用于发出HTTP请求的单头C 43 43 库 您可以将它包含在项目中并使用它 HTTPRequest在macOS Windows Haiku BSD和GNU Linux上进行了测试 xff
  • 小程序、公众号开发报code been used(40163)或invalid code(40029)错误,解决方案--之--搞清楚微信的登录机制,保存登录状态!!!

    x1f4d6 前言 做微信小程序或公众号开发 xff0c 有时我们为了管理用户 xff0c 需要获取用户的openid xff0c unionId等信息 这时会用到微信提供的接口 xff1a code2Session code2Sessio
  • 使用git在vscode中进行版本控制

    版本控制是一件非常cool的事 xff0c 可以将我们的代码按照版本存储 1 首先我们选择一个版本控制工具 xff0c 这里我们选择git xff0c 点击下载安装 xff0c 安装时选择vscode编辑器 2 安装好了之后打开vscode
  • 2.3.1 参数服务器理论模型

    ROS入门 2 3 1 参数服务器理论模型 ROS入门 理论与实践 视频教程镇楼 参数服务器实现是最为简单的 xff0c 该模型如下图所示 该模型中涉及到三个角色 ROS Master 管理者 Talker 参数设置者 Listener 参
  • 4.6.3 编码设置参数

    ROS入门 4 6 3 编码设置参数 ROS入门 理论与实践 视频教程镇楼 编码的方式可以更方便的设置 全局 相对与私有参数 1 C 43 43 实现 在 C 43 43 中 xff0c 可以使用 ros param 或者 ros Node
  • 5.1 TF坐标变换

    ROS入门 5 1 TF坐标变换 ROS入门 理论与实践 视频教程镇楼 机器人系统上 xff0c 有多个传感器 xff0c 如激光雷达 摄像头等 xff0c 有的传感器是可以感知机器人周边的物体方位 或者称之为 坐标 xff0c 横向 纵向
  • 10.1.3 action通信自定义action文件调用(Python)

    ROS入门 10 1 3 action通信自定义action文件调用 Python ROS入门 理论与实践 视频教程镇楼 需求 创建两个ROS 节点 xff0c 服务器和客户端 xff0c 客户端可以向服务器发送目标数据N 一个整型数据 服
  • rosdep

    rosdep 初始化时异常解决方案 rosdep 初始化时异常解决 视频教程 安装构建依赖 在 noetic 最初发布时 xff0c 和其他历史版本稍有差异的是 没有安装构建依赖这一步骤 随着 noetic 不断完善 xff0c 官方补齐了
  • springboot应用集成prometheus监控

    环境参数 xff1a 运行命令 xff1a 1 uname xff0d a xff08 Linux查看版本当前操作系统内核信息 xff09 2 cat proc version xff08 Linux查看当前操作系统版本信息 xff09 3
  • [NVIDIA Jetson Xavier Nx]从刷机烧录到环境配置 记录

    目录 前言一 开机烧录二 环境配置Cuda环境变量配置更新源python环境配置安装Jtop 内存 CPU GPU等等资源监视工具 前言 对进行NVIDIA Jetson Xavier Nx环境配置进行记录 一 开机烧录 参考下面的博客 x
  • 最近处理的报错 -DCMAKE_BUILD_TYPE=Debug

    1 error 39 nullptr 39 was not declared in this scope 解决方法 使用的是QTcreator的pro文件 然后缺少相应关于c 43 43 11的设置 点pro文件中加载的东西如下 QMAKE
  • Halcon 单相机标定

    原文链接 xff1a https blog csdn net weixin 43197380 article details 90438976 comments 13104885 一 理论 为什么要进行单相机标定 xff1f 广义 xff1
  • 将图片嵌入Markdown文档

    将图片嵌入Markdown文档中是一个比较难受的事情 一般大家都会将图片存入本地某个路径或者网络存储空间 xff0c 使用URL链接的形式插入图片 image url to image 将图片放到本地的时候如果想将文档分享给朋友或者换台电脑
  • 自定义的串口通信协议

    自定义的通信协议 自定义一主多从串口通讯 1硬件基础两个从机的 Tx 是相互连接的 xff0c 导致一个从机在需要发送数据时发不出去了 协议思路数据包封装和解封装 树莓派python串口的使用注意更改树莓派串口设备驱动关闭控制台功能pyth
  • Linux串口驱动程序(4)-数据发送

    1 tty数据发送调用关系 怎么样才能找到发送数据所使用的函数呢 xff1f 打开uart register driver函数 xff0c 找到里面的tty register driver xff0c 转到定义 xff0c 这里调用了tty