从Linux的tty_struct指针获取驱动上下文

news2024/10/7 14:31:02

背景

问题

前段时间开发一个tty驱动,用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景,下位机应用将上报内容写入一个驱动创建的tty设备,tty子系统将应用的输入转发给tty驱动,tty驱动将其转换成对SPI从设备(即GPIB扩展板)的写入,SPI从设备再将收到的SPI消息转换成GPIB消息发送给上位机
GPIB拓扑

实现tty_operationswrite接口时,我是这么获取驱动上下文的:

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_ctxstruct 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宏返回了正确的驱动上下文地址。

总结

  1. tty_struct指针类似于file_operations接口的open方法的输出参数file指针,都对应内核自动分配的一个对象,其地址是不可以用于container_of宏的,但是它的成员private_data可以用于container_of宏,因为后者的值是驱动填写的。
  2. container_of宏的第一个参数是结构体成员地址,这个结构体成员一般是个对象,不建议选地址类成员,因为如果是地址,则该成员很可能是复制过的,那么你通过给container_of宏提供二级指针(指针成员的地址就是二级指针)获取的ctx对象,很可能是错的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1117287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统 - 《银行家算法》

(一)安全序列 你是一位成功的商人,手里掌握着 100 个w的资金 … 有三个企业想找你贷款,分别是 企业 B 、企业 A 、企业 T ,为描述方便,简称 BAT 。 B 表示:“咱们的项目很有前景,…

中枢听觉处理障碍的行为干预方法

作者:听觉健康 在数十年前,中枢听觉处理障碍(CAPD)的研究已经引起了多学科的关注。1937年,Samuel Orton提出某些儿童的学习障碍与不能有效利用听觉有关。Myklebust是提出“中枢性听力障碍”引起儿童语言学习障碍的先驱者之一。二十世纪五十年…

【lesson13】进程控制初识

文章目录 进程创建 进程创建 请你描述一下,fork创建子进程操作系统都做了什么? fork创建子进程,系统里多了一个进程,进程 内核数据结构 进程代码数据,内核数据结构由OS维护,进程代码数据一般由磁盘维护。…

C++类和对象(1)

C类和对象(1) C新关键字及语法引用引用的底层原理引用使用的注意事项 auto范围for C结构体新特性C类的特性C类与结构体区别构造函数定义调用 析构函数调用 C新关键字及语法 引用 引用是C加入的新类型,引用是变量的别名,在整体上…

华为OD机试 - TLV格式 - 逻辑分析(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

LeetCode:2316. 统计无向图中无法互相到达点对数(C++)

目录 2316. 统计无向图中无法互相到达点对数 题目描述: 实现代码与解析: 并查集 原理思路: 2316. 统计无向图中无法互相到达点对数 题目描述: 给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为…

stable diffusion如何解决gradio外链无法开启的问题

问题确认 为了确认gradio开启不了是gradio库的问题还是stable diffusion的问题,可以先执行这样一段demo代码 import gradio as grdef greet(name):return "Hello " name "!"demo gr.Interface(fngreet, inputs"text", outputs&q…

Spring Cloud 之 Sentinel简介与GATEWAY整合实现

简介 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 熔断 …

Damask使用指南-Hcp结构(镁(考虑孪晶))孪晶如何加入

1,首先利用geom布种子,种子数为40,模型空间尺寸为64*64*1(表示二维平面问题)代码: 2,根据布种区域生成voronoi镶嵌的晶体结构 代码: 3 检查结构是否正确生成 4,利用dama…

61 不同路径

不同路径 重点:从左上角移动到右下角,m-1次向右,n-1次向下题解1 DP降维——滚动数组 题解2 求解组合 C m n − 2 m − 1 C^{m-1}_{mn-2} Cmn−2m−1​的值 一个机器人位于一个 m x n 网格的 左上角 (起始点在下图中标记为 “St…

自己动手写编译器:c 语言模板中的输入模块设计

使用过“框架”的同学都能感受到“框架”带来的方便。所谓”框架“本质上就是一系列代码安排帮助我们完成脏活累活,或者复杂的工作流程后,把处理结果交给我们提供的代码。本节我们要完成的 c 语言模板也是一个框架,它也需要做一系列脏活累活&…

鲲鹏+麒麟V10 mysql8.0适配

检查是否已安装数据库服务 for i in rpm -qa | grep mysql;do rpm -e --nodeps $i;done yum源地址: http://repo.mysql.com/yum/mysql-8.0-community/el/8/aarch64/ 配置yum源: 将mysql相关的rpm包都下载到指定文件里,留作以后考用 yum reins…

UE4 距离场

在项目设置的渲染模块可打开距离场 把该节点连上,该节点的意思是,距离表面越近,材质显示值为0 不接近表面时: 接近表面时 可勾选该值即可看到距离场具体效果: 未接触表面时: 接触表面时: 产生…

2024年仁爱学院专升本招生专业对应范围专业目录更新的通知

天津仁爱学院2024年高职升本科招生专业对应范围专业目录 为了更好的进行天津仁爱学院专升本工作,动画专业不分文理进行录取。为了进一步提升录取专业的培养需要,请同学们复习专业课时加强专业课学习,请同学们在报考时关注天津仁爱学院招生章…

DLP是如何防止数据泄露的?

根据相关调查数据,未来五年全球企业数据泄露防护(DLP)市场预计将以21.03%的复合年增长率高速增长,到2026年市场规模将达到62.65亿美元。 PC访问地址:获取详细资料 https://isite.baidu.com/site/wjz012xr/2eae091d-1b…

2023年金九银十面经,假的今年没有金九银十

24岁的我选择了裸辞 前言 说实话选择裸辞后很迷茫,但是又不想在原本的公司上班,目前处于昏昏沉沉的状态,工作也是混一天是一天,没有了什么明确的目标,不知道屏幕前的你们有没有这种感觉,目前想着休息一段时间&#xff…

基础框架 Spring

引言 我们常说,Java 程序员不会 Spring,那还叫 Java 程序员吗?由此可见Spring在Java领域的重要性,本章我们就来谈谈 Spring 到底是何方神圣? 一、Spring 核心概念(重要) 1、Spring 是什么&am…

RGB彩色图、Depth深度图

💦彩色图,深度图——》信息缺乏。如,颜色相近导致位置信息丢失 💦深度图——》相近深度的物体,因为颜色或纹理的丢失,导致难区分 深度图并不可以直接使用, 因为深度图只能反映出了物体在三维空…

Oracle数据库完整卸载的完整步骤

时间:2023-03-15来源:系统城装机大师作者:佚名 1、停止所有Oracle服务 进入计算机管理,在服务中,找到oracle开头的所有服务,右击选择停止。 快捷键:ctrlshiftesc打开任务管理器 文章来源 Or…

PACS(Picture Archiving and Communications System)图像存储与传输系统源码

PACS(Picture Archiving and Communications System)——图像存储与传输系统,和医院信息化及数字化的目标紧密关联,它是专门为现代化医院的影像管理而设计的包括数字化医学图像信息的采集、显示、处理、存储、诊断、输出、管理、查…