从Linux的tty_struct指针获取驱动上下文
背景
问题
前段时间开发一个tty驱动,用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景,下位机应用将上报内容写入一个驱动创建的tty设备,tty子系统将应用的输入转发给tty驱动,tty驱动将其转换成对SPI从设备
(即GPIB扩展板)的写入,SPI从设备
再将收到的SPI消息转换成GPIB消息
发送给上位机
。
实现tty_operations
的write
接口时,我是这么获取驱动上下文
的:
struct gpib_tty_ctx {struct tty_port port;struct tty_struct mgr; // 其实是无效的成员struct tty_driver *tty_drv;struct spi_device *spi_dev;struct gpib_spi_ctx *spi_ctx;struct mutex tty_lock;u32 activated:1;const u8 *pend_tx_buf;u32 pend_tx_len;
};static int gpib_tty_write(struct tty_struct * tty, const unsigned char *buf, int count)
{struct gpib_tty_ctx *ctx = container_of(tty, struct gpib_tty_ctx, mgr);// 通过ctx指针访问上下文结构体gpib_tty_ctx的驱动私有字段,完成write功能return count;
}
但是实际执行的时候,触发了空指针异常
,且空指针的值并不是0x0这种典型值,而是带一点偏移。
问题定位
经定位,是我对tty子系统的理解有问题,write
方法的第一个入参tty
,并不是gpib_tty_ctx
的struct tty_struct mgr
成员的地址,而是tty子系统在运行时自动创建的一个匿名tty_struct
对象的地址!因此我用container_of
宏获取到的gpib_tty_ctx
对象地址也是一个无效地址!
解决
注意到tty_struct
结构体包含一个类型为struct tty_port
的指针port
:
struct tty_struct {struct kref kref;int index;struct device *dev;struct tty_driver *driver;struct tty_port *port; // 指向用户驱动创建并初始化的tty_port对象const struct tty_operations *ops;struct tty_ldisc *ldisc;struct ld_semaphore ldisc_sem;// ...
};
它应该就是指向驱动之前创建并初始化的gpib_tty_ctx.port
对象,这个对象本身是没有被复制的,因此我可以将这个指针传递给container_of
宏:
struct gpib_tty_ctx *ctx = container_of(tty->port, struct gpib_tty_ctx, port);
经测试,新的container_of
宏返回了正确的驱动上下文地址。
总结
tty_struct
指针类似于file_operations
接口的open
方法的输出参数file
指针,都对应内核自动分配的一个对象,其地址是不可以用于container_of
宏的,但是它的成员private_data
可以用于container_of
宏,因为后者的值是驱动填写的。container_of
宏的第一个参数是结构体成员
的地址
,这个结构体成员
一般是个对象,不建议选地址类成员,因为如果是地址,则该成员很可能是复制过的,那么你通过给container_of
宏提供二级指针(指针成员的地址就是二级指针)获取的ctx对象,很可能是错的。
相关文章:

从Linux的tty_struct指针获取驱动上下文
背景 问题 前段时间开发一个tty驱动,用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景,下位机应用将上报内容写入一个驱动创建的tty设备,tty子系统将应用的输入转发给tty驱动,tty驱动将其转换成对SPI从设备࿰…...

PHP WAP餐厅点餐系统mysql数据库web结构apache计算机软件工程网页wamp
一、源码特点 PHP餐厅点餐系统是一套完善的web设计系统,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 PHP WAP餐厅点餐系统 代码 https://download.csdn.net/download/qq_41221322/88440001 二、…...

智慧公厕改变城市生活,厕所革命标杆应用解决方案
随着城市化进程的加快,公厕作为城市基础设施的重要组成部分,扮演着不可忽视的角色。然而,传统的公厕粗放型管理模式,已经无法满足市民日益增长的需求。为了提升公厕的管理和服务水平,智慧公厕应运而生。 什么是智慧公…...

YOLOv5改进实战 | 更换主干网络Backbone(四)之轻量化模型MobileNetV3
前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…...

上新啦!请查收云原生虚拟数仓 PieCloudDB 十月动态
PieCloudDB Database 最新动态 PieCloudDB 压缩效率得到提升 为了节省存储空间,降低用户存储费用,PieCloudDB 在压缩率上不断优化,包括: 对 HLL(HyperLogLog)支持游程编码(Run Length Encodi…...
第五章:Python中的集合(上)
Python中的集合 是一组不可重复元素的无序集合。集合通常用于在其中执行成员测试,删除重复项,计算交集、并集和差集等操作。 Python的集合是可迭代对象。具体来说,集合可以通过for循环逐个访问其中的元素。同时,集合还支持一些迭代器相关的方法,例如iter()函数和next()函…...

虚拟机灾备建设中NFS存储直接访问技术应用
NFS(Network File System)是一种网络文件系统,允许不同计算机之间共享文件和目录。在Linux系统中,可以使用NFS协议来访问网络存储。 当新服务器硬盘不足时,旧的服务器硬盘容量大,不拔硬盘的情况下…...
java业务开发常用的配置表及代码
配置表 通过配置表,灵活的配置。 开发中某些经常变更的参数值,加上配置。比如 订单30分钟后失效,需求变更,要改为15分钟,那么直接改配置表就行了,不用发版。 某些关键的容易出错的逻辑,加上一…...
安装Homebrew安装Git(Mac)
使用Homebrew安装Git(Mac) 1 安装Xcode 安装Homebrew之前,需要安装Xcode Comand Line Tools: xcode-select --install 2 安装Homebrew /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/mas…...

[云原生1.] Docker容器的简单介绍和基本管理
文章目录 1. Docker容器的基本概述1.1 简介1.2 容器的优点1.3 Docker与虚拟机的区别1.4 Docker核心组成1.4.1 镜像1.4.2 容器1.4.3 仓库 1.5 容器在内核中支持2种重要技术1.5.1 linux六大namespace(命名空间) 1.6 Docker的使用场景 2. Docker的部署2.1 前…...
JSR303数据校验
Component //注册bean ConfigurationProperties(prefix "person") Validated //数据校验 public class Person { Email(message"邮箱格式错误") //name必须是邮箱格式 private String name; } 使用数据校验,可以保证数据的正确性!…...

JavaCV + FFmpeg 播放音视频
JavaCV FFmpeg 播放音视频 1、导入JavaCV库1.1 使用ffmpeg必要库1.2 简单FFmpeg命令 待续~~~~ FFmpeg documentation bytedeco/javacv - GitHub 1、导入JavaCV库 gradle下面这种会导入javacv-platform所有包,非常耗时:https://repo.maven.apache.org/…...

万能DIY预约小程序源码系统 上门预约服务小程序搭建 适用于各种预约场景 自由DIY功能模块
在这个快节奏的时代,预约服务已经成为了我们日常生活的一部分。从看病挂号到餐厅预订,从美发美容到家政服务,预约已经深入到了各个领域。然而,传统的预约方式存在着许多不便,如电话预约、在线填写表格等,不…...
边缘检测算法
边缘检测算法是在数字图像处理中常用的一种技术,用于检测图像中物体边缘的位置。以下是几种常见的边缘检测算法: Sobel算子:Sobel算子是一种基于梯度的算法,通过计算图像的水平和垂直方向的梯度值,并将其组合起来得到边…...

数据结构与算法-树
树 🎈1.树和二叉树🎈2.树🔭2.1树的定义🔭2.2树的4种表示方法🔭2.3树的基本术语🔭2.4树的抽象数据类型定义 🎈3.二叉树🔭3.1二叉树的定义🔭3.2二叉树的抽象数据类型定义&a…...
【Bug排查】Uncaught (in promise) Error: Infinite redirect in navigation guard
记一次Bug排查 今日在做尚硅谷的商品甄选项目时,遇到无法登录的问题:报错Uncaught (in promise) Error: Infinite redirect in navigation guard 一开始我去搜CSDN,都说是路由的问题,我对前端也不了解,试着改了一下&…...
ant使用第三方任务
ant提供了一个插件机制来使用第三方的任务。为了使用第三方的任务,需要做两步: 将它们的实现放在ant能找到的地方。声明任务 声明任务的几种方法: 声明一个任务:利用<taskdef name"taskname" classname"Impl…...

MySQL 性能分析
MySQL 性能分析 对 mysql 进行性能分析,主要就是提升查询的效率,其中索引占主导地位。对 mysql 进行性能分析主要有如下几种方式: 方式一:查看 sql 执行频次 show global status like ‘Com_______’; // global 表示全局 show s…...

【MySQL】数据库——库操作
文章目录 1. 创建数据库[IF NOT EXISTS] 的使用 2. 删除库3. 数据库的编码问题查看系统默认支持的字符集查看系统默认支持的校验集只查看 database的校验集指定编码创建数据库修改字符集修改校验集验证规则对数据库的影响utf8_general_ci ——不区分大小写utf8_bin ——区分大小…...
Python 轻量 ORM peewee 上手
介绍 有时候需要用 Python 直接操作数据库, 手工撸 SQL 倒也不是不能行, 但是总觉得有点背离了 人生苦短, 我用 Python 的初心, 习惯了 SQLAlchemy 的直接操作后, 就变懒了. 但是对于比较简单的数据库操作场景, 再跑一套 SQLAlchemy 又显得有些臃肿, 这次上手轻量 Python ORM …...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...