UART驱动情景分析-write
一、write过程分析
- App写:
- 使用行规程来写
- 数据最终存入uart_state->xmit的buffer里
- 硬件发送:
- 使用硬件驱动中uart_ops->start_tx开始发送
- 具体的发送方式有两种:通过DMA、通过中断
- 中断方式:
- 方法1:直接使能tx empty中断,一开始tx buffer为空,在中断里填入数据
- 方法2:写不封数据到tx fifo,使能中断,剩下的数据再次中断里继续发送
二、tty_write
文件在driver\tty\tty_io.c
static ssize_t tty_write(struct file *file, const char __user *buf,size_t count, loff_t *ppos)
{struct tty_struct *tty = file_tty(file);struct tty_ldisc *ld;//...if (!ld->ops->write)ret = -EIO;elseret = do_tty_write(ld->ops->write, tty, file, buf, count); //使用行规程里的惭怍函数,进行写入//tty_ldisc->tty_ldisc_ops->writetty_ldisc_deref(ld);return ret;
}
三、ldisk write
文件drivers\tty\n_tty.c
static struct tty_ldisc_ops n_tty_ops = { //tty_ldisc_ops惭怍函数,实例结构体n_tty_ops.magic = TTY_LDISC_MAGIC,.name = "n_tty",.open = n_tty_open,.close = n_tty_close,.flush_buffer = n_tty_flush_buffer,.read = n_tty_read,.write = n_tty_write, //上面ld->ops->write,调用的是这个函数//...
};static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,const unsigned char *buf, size_t nr)
{//...while (1) {//...if (O_OPOST(tty)) {//...} else {struct n_tty_data *ldata = tty->disc_data;while (nr > 0) {mutex_lock(&ldata->output_lock);c = tty->ops->write(tty, b, nr); //tty_struct->tty_operationsmutex_unlock(&ldata->output_lock);//...}}if (!nr)break;if (file->f_flags & O_NONBLOCK) { //非阻塞方式的话,直接返回,不等数据发送完retval = -EAGAIN;break;}up_read(&tty->termios_rwsem);wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); //阻塞方式,等待发送完毕down_read(&tty->termios_rwsem);}//...
}
四、uart_write
文件:drivers\tty\serial\serial_core.c
static const struct tty_operations uart_ops = {.open = uart_open,.close = uart_close,.write = uart_write,//....
};static int uart_write(struct tty_struct *tty,const unsigned char *buf, int count)
{struct uart_state *state = tty->driver_data;struct uart_port *port;struct circ_buf *circ;unsigned long flags;int c, ret = 0;//...port = uart_port_lock(state, flags);circ = &state->xmit; //赋值寄存器地址//...while (port) {//...memcpy(circ->buf + circ->head, buf, c); //把数据存入xmit buffercirc->head = (circ->head + c) & (UART_XMIT_SIZE - 1);buf += c;count -= c;ret += c;}__uart_start(tty); //启动串口发送数据uart_port_unlock(port, flags);return ret;
}static void __uart_start(struct tty_struct *tty)
{struct uart_state *state = tty->driver_data;struct uart_port *port = state->uart_port;if (port && !uart_tx_stopped(port))port->ops->start_tx(port); //uart_port->uart_ops->start_tx
}
五、硬件相关的发送
相关文件:drivers\tty\serial\imx.c
static const struct uart_ops imx_uart_pops = {.tx_empty = imx_uart_tx_empty,.set_mctrl = imx_uart_set_mctrl,.get_mctrl = imx_uart_get_mctrl,.stop_tx = imx_uart_stop_tx,.start_tx = imx_uart_start_tx,.stop_rx = imx_uart_stop_rx,//...
};static void imx_uart_start_tx(struct uart_port *port)
{//...if (!sport->dma_is_enabled) { //不适用DMA时,比较容易理解,以它为例ucr1 = imx_uart_readl(sport, UCR1);//Transimiter Empty Interrupt Enable,发送buffer为空时,就产生中断//在中断函数里发送字符imx_uart_writel(sport, ucr1 | UCR1_TXMPTYEN, UCR1);}if (sport->dma_is_enabled) {//...}
}
一开始时,发送buffer肯定为空,就会立即产生中断:
static irqreturn_t imx_uart_txint(int irq, void *dev_id)
{struct imx_port *sport = dev_id;unsigned long flags;spin_lock_irqsave(&sport->port.lock, flags);imx_uart_transmit_buffer(sport);spin_unlock_irqrestore(&sport->port.lock, flags);return IRQ_HANDLED;
}static inline void imx_uart_transmit_buffer(struct imx_port *sport)
{struct circ_buf *xmit = &sport->port.state->xmit;//...while (!uart_circ_empty(xmit) &&!(imx_uart_readl(sport, imx_uart_uts_reg(sport)) & UTS_TXFULL)) {/* send xmit->buf[xmit->tail]* out the port here *///UART TX FIFO未满时,从xmit buffer取出数据写入FIFO,更新统计信息imx_uart_writel(sport, xmit->buf[xmit->tail], URTX0);xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);sport->port.icount.tx++;}if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)uart_write_wakeup(&sport->port);if (uart_circ_empty(xmit))imx_uart_stop_tx(&sport->port);
}
相关文章:

UART驱动情景分析-write
一、write过程分析 App写: 使用行规程来写数据最终存入uart_state->xmit的buffer里 硬件发送: 使用硬件驱动中uart_ops->start_tx开始发送具体的发送方式有两种:通过DMA、通过中断 中断方式: 方法1:直接使能tx …...

Metasploit入门到高级【第四章】
来自公粽号:Kali与编程预计更新第一章:Metasploit 简介 Metasploit 是什么Metasploit 的历史和发展Metasploit 的组成部分 第二章:Kali Linux 入门 Kali Linux 简介Kali Linux 安装和配置常用命令和工具介绍 第三章:Metasploi…...

java 继承super
在java继承中,如果子类继承父类,在子类中要给用构造器给父类的属性赋值,需要用到 super 举例,Son类继承Father 类,便于理解 在 new Son(String name, int age) 传入name,和age的值 将会调用Son这个构造器…...

Java学习笔记——多态
2.1 概述 引入 多态是继封装、继承之后,面向对象的第三大特征。 生活中,比如跑的动作,小猫,小狗和大象,跑起来都是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来是不一样的。可见&#x…...

Python处理JSON数据
Python和JSON JavaScript Object Notation (JSON) 是一种轻量级的数据交换格式,通常用于Web应用程序之间的数据交换。JSON的设计使得它非常易于人和机器阅读和编写。JSON数据格式与Python数据结构非常相似,因此Python中提供了一个json模块,用…...

JVM信息查询命令
1、查询jar包运行进程 jps #通过jps命令找出jar的进程IDps -ef|grep xxxx #通过包名找出进程ID2、查询JVM的堆信息 jmap -heap pid #通过jmap命令查询堆信息rootd57bff9f-c8nvn:/apps# jmap -heap 6 Picked up JAVA_TOOL_OPTIONS: -Xloggc:/data/tsf_apm/monitor/jvm…...

redis 面试题
🍕 redis 面试题常规问题什么是 Redis?为什么要使用 Redis?Redis 一般有哪些使用场景?Redis 为什么快?数据类型和数据结构Redis有哪些数据类型?常用操作和应用Bitmaps (位图) | 二进制计数与过滤计数器记录…...

SpringCloud微服务技术栈.黑马跟学(十二)
SpringCloud微服务技术栈.黑马跟学 十二今日目标服务异步通信-高级篇1.消息可靠性1.1.生产者消息确认1.1.1.修改配置1.1.2.定义Return回调1.1.3.定义ConfirmCallback1.2.消息持久化1.2.1.交换机持久化1.2.2.队列持久化1.2.3.消息持久化1.3.消费者消息确认1.3.1.演示none模式1.3…...

HashMap集合存储学生对象并遍历
需求:创建一个HashMap集合,键是学生对象(Student),值是居住地。存储多个键值对元素,并遍历。 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象 思路: 定义…...

“提效”|教你用ChatGPT玩数据
ChatGPT与数据分析(二) 上文给简单聊了一下为什么ChatGPT不能取代数据分析师,本文我们来深入感受一下如何让GPT帮助数据分析师“提效”。 场景一:SQL取数 背景:多数数据分析师都要用SQL语言从数据库中提取数据&#x…...

https://app.hackthebox.com/machines/Inject
https://app.hackthebox.com/machines/Inject Ref: 1.https://blog.csdn.net/qq_58869808/article/details/129505388 2.https://blog.csdn.net/m0_73998094/article/details/129474782 info collecting ┌──(kwkl㉿kwkl)-[~/HODL/htb/Inject] └─$ nmap -A …...

Java Web 实战 15 - 计算机网络之网络编程套接字
文章目录一 . 网络编程中的基本概念1.1 网络编程1.2 客户端(client) / 服务器(server)1.3 请求(request) / 响应(response)1.4 客户端和服务器之间的交互数据1.4.1 一问一答1.4.2 多问一答1.4.3 一问多答1.4.4 多问多答二 . socket 套接字2.1 UDP 的 Socket API2.1.1 引子2.1.2…...

基于pdf2docx模块Python实现批量将PDF转Word文档(安装+完整代码教程)
PDF文件是一种常见的文档格式,但是在编辑和修改时不太方便,因为PDF本质上是一种静态的文档格式。因此,有时候我们需要将PDF文件转换成Word格式,以便更好地编辑和修改文档。在本篇文章中,我们将介绍如何使用Python实现P…...

3.21~3.22
识编程语言中的,局部变量,全局变量,以及变量生存周期,整形,浮点型数据的内存表示,od的内存窗口的使用 先看一个代码样例 #include<windows.h> #include<stdio.h>#pragma warning(disable:499…...

Chromium 改造实录:增加 MPEG TS 格式支持
在《选择最新 Chromium,支持 H264 / H265》一文中,记录了我通过升级 Chromium 版本解决了 H264 / H265 视频支持难题。然而难题接踵而至,这次的难题是 MPEG TS 流的支持。MPEG2-TS 传输流广泛应用于数字电视广播系统,所以是一个不…...

性能优化之-事件代理
js中的事件委托或是事件代理简单理解 事件委托也叫事件代理,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。 概述&#x…...

MSDS 即化学品安全说明书
MSDS 即化学品安全说明书,亦可译为化学品安全技术说明书或化学品安全数据说明书,是化学品生产商和进口商用来阐明化学品的理化特性(如PH值,闪点,易燃度,反应活性等)以及对使用者的健康ÿ…...

真人手办没法实现网购?我有一个好办法!
记得以前在网上看到过一个冷笑话式的问答,问的是中国最早的手办是什么,有网友回答是秦始皇兵马俑,这个抖机灵式的回答简直妙得让人会心一笑。 你接触过手办吗? 提到手办,大家第一时间想到的,肯定都会是各…...

2019湖南省大学生程序设计竞赛题解(D)
D-Modulo Nine 很妙的类似区间dp, 我自己是想不到,本题解题思路来自学长的博客: 长沙橘子猫 题意 有一个长度为 nnn 的序列,你可以给每个位置填 0∼90\sim90∼9 的一个数,有 mmm 个限制,每个限制 [li,ri…...

【开发】中间件——RocketMQ
分布式消息系统 RocketMQ概念,用途,特性安装RocketMQ掌握RocketMQ的api使用对producer、consumer进行详解了解RocketMQ的存储特点 简介及相关概念JavaAPISpringBoot整合RocketMQ消息的顺序收发消息系统的事务、存储、重试策略消息系统的集群 RocketMQ R…...

36 UnitTest框架 - 参数化
目录 一、参数化环境准备 1、方式一:在终端(cmd)安装parameterized 2、方式二:在Pycharm中安装parameterized 二、参数化 1、什么事参数化? 2、参数化引入案例 (1)需求 (2&a…...

Qt源码阅读(四) 事件循环
事件系统 文章为本人理解,如有理解不到位之处,烦请各位指正。 文章目录事件系统什么是事件循环?事件是如何产生的?sendEventpostEvent事件是如何处理的?事件循环是怎么遍历的?事件过滤器event夹带私货时间Q…...

银行数字化转型导师坚鹏:银行数字化领导力提升之道
银行数字化领导力提升之道 ——融合中西智慧,践行知行合一思想,实现知行果合一 课程背景: 很多银行存在以下问题:不知道如何领导数字员工?不清楚银行数字化领导力模型的内涵?不知道如何开展银行数字化…...

Vue2 -- 自定义单选内容的单选框组件
自定义单选内容的单选框组件 之前做的一个项目,在项目中有一个关于人员权限分配的功能,给人员指定各个模块的权限信息,分为 write 可写权限read 可读权限none 没有权限 项目要求画面中只显示 W R 两个按钮控制指定权限信息,都不…...

让PyTorch训练速度更快,你需要掌握这17种方法
掌握这 17 种方法,用最省力的方式,加速你的 Pytorch 深度学习训练。近日,Reddit 上一个帖子热度爆表。主题内容是关于怎样加速 PyTorch 训练。原文作者是来自苏黎世联邦理工学院的计算机科学硕士生 LORENZ KUHN,文章向我们介绍了在…...

LeetCode-309. 最佳买卖股票时机含冷冻期
目录题目思路动态规划题目来源 309. 最佳买卖股票时机含冷冻期 题目思路 每天最多只可能有三种状态中的一种 0表示当前处于买入状态(持有股票) 1表示当前处于卖出状态(不持有股票) 2表示当前处于冷冻状态 设dp[i][j]表示i - 1天状态为j时所拥有的最大现金 dp[i][0] Math.ma…...

AUTOSAR知识点Com(七):CANSM初认知
目录 1、概述 2、CanSM主要做什么 2.1、CAN控制器状态管理 2.2、CAN收发器状态管理 2.3、Busoff检测 1、概述 CANSM(Controller Area Network State Manager)是AUTOSAR(Automotive Open System Architecture)标准中的一个模块…...

递归:斐波那契数列、递归实现指数型枚举、递归实现排列型枚举
递归:O(2^n) 调用自己 例题及代码模板: 斐波那契数列 输入一个整数 n ,求斐波那契数列的第 n 项。 假定从 0 开始,第 0 项为 0。 数据范围 0≤n≤39 样例 输入整数 n5 返回 5 #include <iostream> #include <cstring&g…...

oracle模糊查询时字段内容包含下划线的解决办法
最近项目中遇到一个关于模糊查询问题。表tabA中的字段name的值有下划线的情况,在模糊查询时发现查询的记录不对。 表的结构 表名:tabA id name sex 1 test_601 1 2 test_602 2 3 test16 1 4 t…...

C++:explicit关键字
C中的explicit关键字只能用于修饰只有一个参数的类构造函数,它的作用是表明该构造函数是显示的,而非隐式的,跟它相对应的另一个关键字是implicit,意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。那么显示声…...