Linux 内核学习(7) --- 字符设备驱动
字符设备驱动程序
Linux 中主要有三类设备的驱动程序,分别是字符设备驱动程序,块设备驱动程序和网络设备驱动程序
字符设备是指在 I/O
传输过程中以字符为单位进行传输的设备,例如键盘,打印机等,字符设备的驱动程序结构如下图所示:
字符设备可以通过文件节点来访问,设备文件和普通文件差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道,当然也存在数据区特性的字符设备,访问它们可以前后移动访问位置,比如FrameBuffer Device
就是这样一个设备,app
可以用 mmap
或者 lseek
访问获取整个图像
字符设备文件类型是 c(char),设备文件没有文件大小,取而代之的是两个号:主设备号 和 次设备号
字符设备驱动程序实现逻辑
Linux 内部一切设备皆文件,所有的硬件设备操作到应用层都会抽象为文件的操作,Linux
访问文件的基本逻辑如下:
Linux
文件系统中,每一个文件都用一个struct inode 结构体来描述,这个结构体里面记录这个文件的所有信息,比如文件类型,访问权限等Linux
操作系统中,每个驱动程序在应用层 /dev 目录下都会有一个设备文件和它对应,称为设备节点,该设备节点存在主设备号和次设备号- 每打开一次文件,
Linux
的VFS
都会分配一个struct file
结构体来描述打开的文件,该结构体用于维护文件打开的权限,文件指针偏移值,私有的内存信息等
驱动程序的主设备号和次设备号信息保存在struct cdev
结构中
struct cdev {struct kobject kobj;struct module *owner;const struct file_operations *ops;struct list_head list;dev_t dev;unsigned int count;
};
字符设备驱动的调用逻辑:
open
函数打开设备文件,可以根据设备文件对应的struct inode
结构体描述的信息,判断当前的要操作的设备类型,还会分配一个struct file
结构体- 根据
struct inode
结构中记录的设备号,可以找到对应的驱动程序,Linux 中每个字符设备都有一个struct cdev
结构体来对应,struct cdev
描述了字符设备的所有信息,其中最重要的就是字符设备的操作接口 - 找到
struct cdev
结构体后,linux 内核会将struct cdev
结构体所在的内存空间首地址记录在struct inode
结构体的i_cdev
成员中,将struct cdev
结构体中记录的函数操作接口记录在struct file
结构体的fops
成员中 - 任务完成,
VFS
会给应用层返回一个文件描述符,这个fd
是和struct file
结构体想对应的,上层应用程序的调用就可以通过 fd 找到对应的 struct file,由struct file
找到操作字符设备接口的函数了
代码路径:/include/linux/fs.h
struct file
类型的实现:
struct file {union {struct llist_node fu_llist;struct rcu_head fu_rcuhead;} f_u;struct path f_path;struct inode *f_inode; /* cached value */u64 f_version;const struct file_operations *f_op;.../* needed for tty driver, and maybe others */void *private_data;.....
};
private_data
可以用于保存驱动的私有数据,用于在驱动的各个操作函数之间共享
file
数据结构中包含 inode 数据结构,struct inode *f_inode
struct inode *inode = file_inode(file);
struct inode {umode_t i_mode;unsigned short i_opflags;kuid_t i_uid;kgid_t i_gid;unsigned int i_flags;.....dev_t i_rdev; //保存字符设备驱动设备号
}
其中的 dev_t i_rdev; 包含了设备的主次设备号
主次设备号 是 一个32位的数 12
位表示主设备号 20
位表示次设备号
/include/linux/fs.h 提供下面操作设备号的函数
// inlude/linux/kdev_t.h
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))//从 inode 中获取主次设备号 /include/linux/fs.h
static inline unsigned iminor(const struct inode *inode)
static inline unsigned imajor(const struct inode *inode)
struct file_operations
里面包含了驱动操作函数的函数指针
struct file_operations {struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);......
}
可以看到驱动程序的操作函数中,参数都会带有struct file *,指向内核分配的struct file 类型
编写字符设备驱动
- 实现驱动模块的加载和卸载入口函数
module_init(drm_core_init);
module_exit(drm_core_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxxxx");
MODULE_DESCRIPTION("A module used for show task of each thread!");
module_init(fbmem_init);
在 linux
中,所有标志为 __init
的函数在连接的时候都放在 .init.text
这个区段,此外,所有的__init
函数
在区段 .initcall.init
中还保存了一份函数指针,在初始化内核会通过这些函数指针调用这些 __init 函数,并
在初始化完成之后,释放 init区段,(包括 .init.text
.initcall.init
)
module_exit(fbmem_exit);
一般以 __exit 标志命名。 主要完成的工作:
- 注销设备
- 对于申请的内存需要动态释放
- 释放硬件资源 终端 DMA通道 I/O 端口 I/O 内存管理
- 开启了硬件一定要关闭
- 申请主设备号
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
extern int register_chrdev_region(dev_t, unsigned, const char *);
- 手动/自动创建设备节点
设备节点可以手动创建 mknod /dev/hello 250 0
自动创建设备节点:
Linux 系统中还存在 udev,mdev机制,可以遍历 /sys/class/xxx 下的 uevent 文件,根据这些这些uevent
文件获取创建设备节点的信息,然后调用mknod
程序在/dev
下创建设备节点,结束之后,udev就开始等待内核空间的event
创建设备类的一般流程:
static struct class *cls;
static struct device *test_device;devno = MKDEV(major,minor);
cls = class_create(THIS_MODULE, "democlass");
if(IS_ERR(cls)) {unregister_chrdev(major,"hello");return result;
}
test_device = device_create(cls, NULL, devno, NULL, "hellodevice");
if(IS_ERR(test_device )) {class_destroy(cls);unregister_chrdev(major,"hello");return result;
}
- 实现
file_operation
- 定义一个结构体 static struct file_operations变量,在其中定义一些设备的打开,关闭,读,写,控制函数
字符设备提供给应用程序的流控制接口有 open,close,read,write,ioctl;添加一个字符设备驱动程序的过程,实际上就是给上述操作添加代码的过程,Linux 对这些设备操作统一做了抽象
struct file_operations s3c_rotator_fops = {.owner = THIS_MODULE,.open = dev_fifo_open,.release = xxxx,.mmap = xxx,.ioctl = xxxx,.poll = xxxx,
};
相关文章:
Linux 内核学习(7) --- 字符设备驱动
字符设备驱动程序 Linux 中主要有三类设备的驱动程序,分别是字符设备驱动程序,块设备驱动程序和网络设备驱动程序 字符设备是指在 I/O 传输过程中以字符为单位进行传输的设备,例如键盘,打印机等,字符设备的驱动程序结…...
vue3+vite项目引入tailwindcss
从2025年1月tailwindcss4.0发布开始使用tailwindcss比之前简化很多 1,安装 yarn add tailwindcss tailwindcss/vite2,配置vite.config.js import tailwindcss from tailwindcss/vite;...plugins: [tailwindcss(),...] ...3,在主css文件顶部添加 注意一定是css文件,不能是sc…...
IIS配置SSL
打开iis 如果搜不到iis,要先开 再搜就打得开了 cmd中找到本机ip 用http访问本机ip 把原本的http绑定删了 再用http访问本机ip就不行了 只能用https访问了...
LeetCode:对称二叉树
1、题目描述 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root [1,2,2,null,3,null,3] 输出:false 提示: 树中…...
6天从0到精通:MySQL基础快速入门指南
放在前头 6天从0到精通:MySQL基础快速入门指南 6天从0到精通:MySQL基础快速入门指南 在数据驱动的时代浪潮下,MySQL作为全球最受欢迎的开源关系型数据库管理系统之一,广泛应用于Web开发、数据分析、云计算等多个领域。无论是刚…...
信息论12:从信息增益到信息增益比——决策树中的惩罚机制与应用
从信息增益到信息增益比:决策树中的惩罚机制与应用 引言:当"信息量"遇到"公平性" 在2018年某银行的信用卡风控系统中,数据分析师发现一个诡异现象:客户ID号在决策树模型中竟成为最重要的特征。这个案例揭示…...
C++ -- 哈希扩展
目录 位图 位图概念 位图的实现 位图应用 布隆过滤器 布隆过滤器的提出 布隆过滤器概念 布隆过滤器的插入 布隆过滤器的查找 布隆过滤器的删除 位图 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数…...
AI大模型分类以及Prompt优化技巧
目录 一、AI大模型分类 1、按模态分类 2、按开源性分类 3、按规模分类 4、按用途分类 如何对比和选择大模型 二、Token 如何计算 Token 如何估算Token成本 三、Prompt工程 Prompt优化技巧 基础提示技巧 1、明确指定任何和角色 2、提供详细说明和具体示例 3、使用…...
将本地项目提交到新建的git仓库
方式一: # 登录git,新建git仓库和指定的分支,如master、dev# 下载代码,默认下载master分支 git clone http://10.*.*.67/performance_library/pfme-*.git # 切换到想要提交代码的dev分支 git checkout dev# 添加想要提交的文件 git add .#…...
【wpf】10 C#树形控件高效实现:递归构建与路径查找优化详解
在WPF应用程序开发中,树形控件的实现是常见且具有挑战性的需求。本文将深入解析一套高效树形结构的实现方案,包含递归构建、路径查找优化、动态交互等多个关键技术点。 一、递归构建树形结构 private TreeItem CreateTreeViewItem(TreeNode node) {var…...
低空科技护航珞樱春色,技术引领助推广阔应用
春风拂珞珈,樱海绽放时。赏樱季已接近尾声,作为武汉大学测绘遥感信息工程全国重点实验室的成果转化科技型企业,大势智慧积极参与校园的智能化建设,助力武汉大学的樱花季巡航管理,打造更为安全、有序的赏樱体验。 低空…...
Tiny Machine Learning在人类行为分析中的全面综述
论文标题: 中文:《Tiny Machine Learning在人类行为分析中的全面综述》 英文:A Comprehensive Survey on Tiny Machine Learning for Human Behavior Analysis 作者信息: Ismail Lamaakal, Student Member, IEEE, Siham Essahr…...
8.12 GitHub Sentinel企业级进化:容器化优化×AI监控,效率提升300%实战
GitHub Sentinel 扩展优化与商业化演进路径 关键词:企业级 Agent 扩展性设计、容器化部署优化、多格式报告生成、第三方服务集成、SaaS 服务架构 1. 功能扩展方向 1.1 多格式报告生成技术实现 采用模板引擎与文件流处理技术实现动态报告生成: #mermaid-svg-2BhQlvVsDp5NdL…...
算法-时间复杂度和空间复杂度
刷算法必备时间和空间复杂度,记录下方便查询。 时间复杂度 概念 时间复杂度衡量的是算法 执行所需的时间 随输入规模 n 增长的变化趋势,用大O 表示法描述(通常是看这个循环)。 分类 常数时间O(1) 无论输入多大,执行…...
springboot国家化多语言实现
前言 公司在做国际化项目时需要匹配多语言环境,通过spring实现i18n国际化方便快捷 项目结构 src/ ├── main/ │ ├── java/ │ │ └── com/example/i18ndemo/ │ │ ├── config/ # 配置类 │ │ ├── controller/ # …...
第2章 算法分析基础
2-1 算法的时间复杂度分析 2.1.1 输入规模与基本语句 输入规模:算法处理数据的规模,通常用 n 表示。 基本语句:执行次数与输入规模直接相关的关键操作。 例2.1 顺序查找 int SeqSearch(int A[], int n, int k) { for (int i 0; i < n…...
vue2 计算属性 computed
计算属性他是一个属性,他不是一个函数,使用的时候不要加括号 reduce reduce 是 JavaScript 数组的一个高阶函数,用于对数组中的每个元素执行一个累积计算,最终返回一个单一的值。...
Milvus 向量数据库详解与实践指南
一、Milvus 核心介绍 1. 什么是 Milvus? Milvus 是一款开源、高性能、可扩展的向量数据库,专门为海量向量数据的存储、索引和检索而设计。它支持近似最近邻搜索(ANN),适用于图像检索、自然语言处理(NLP&am…...
记录一次 python 文件环境变量配置-sqlmap.py
第一步:环境变量配置 C:\Users\14913\Downloads\application\3.secure\sqlmap-2025.5.6 或者 C:\Users\14913\Downloads\application\3.secure\sqlmap-2025.5.6 都可以! 第二步 使用 第一步:不再进目录 第二步:不再python … s…...
使用大语言模型进行机器人规划(Robot planning with LLMs)
李升伟 编译 长期规划在机器人学领域可以从经典控制方法与大型语言模型在现实世界知识能力的结合中获益。 在20世纪80年代,机器人学和人工智能(AI)领域的专家提出了莫雷奇悖论,观察到人类看似简单的涉及移动和感知的任务&#x…...
STM32 CAN总线
目录 定时传输CAN简介和硬件电路 CAN简介 主流通信协议对比 编辑 CAN硬件电路 编辑 CAN电平标准 CAN收发器 – TJA1050(高速CAN) CAN物理层特性 帧格式 数据帧 遥控帧 错误帧 过载帧 编辑 帧间隔 编辑 位填充 波形实例 位…...
使用JMeter 编写的测试计划的多个线程组如何生成独立的线程组报告
我有一个测试计划,里面有两个线程组,如下: 添加了一个HTTP请求默认值: 然后我使用如下命令生成的可视化报告是两个线程组合并后的聚合报告。 jmeter -n -t 百度测试计划.jmx -l baidu.txt -e -o ./baidu但是我想要的效果是每…...
RabbitMQ如何保证消息不丢失?
在RabbitMQ中,消息丢失可能发生在三个阶段:生产者发送消息时、消息在RabbitMQ服务器内部传递时、消费者接收消息时。为了保证消息不丢失,需要从这三个方面分别采取措施: 1. 生产者确保消息发送成功 开启确认模式(Conf…...
RAG 的介绍及评价方法
RAG的作用 大模型虽然具备处理复杂语言任务的强大能力,但在知识更新和依赖外部信息的及时性方面存在局限。大模型在训练时捕获的知识通常是静态的,一旦训练完成,模型便不再更新,无法掌握训练数据集之外的最新信息或事件。RAG可以…...
Linux网络新手注意事项与配置指南
Linux系统在网络管理方面提供了丰富的工具和灵活的配置方式,但对于新手来说,掌握正确的操作方法和注意事项至关重要。本文将从网络基础概念、配置工具、安全设置、故障排查以及常见错误等多个方面,结合具体代码示例,详细讲解Linux网络管理的核心内容,帮助新手快速入门并避…...
CI/CD与DevOps流程流程简述(提供思路)
一 CI/CD流程详解:代码集成、测试与发布部署 引言 在软件开发的世界里,CI/CD(持续集成/持续交付)就像是一套精密的流水线,确保代码从开发到上线的整个过程高效、稳定。我作为一名资深的软件工程师,接下来…...
【AWS+Wordpress-准备阶段】AWS注册+创建EC2实例
前言 自学笔记,解决问题为主,亲测有效,欢迎补充。 本地WP文件部署到AWS整体步骤如下:(本文重点:AWS准备完成) 0. [AWS 准备] 注册 AWS 并创建 EC2 实例 ↓ 1. [生成安装包:用 Du…...
FPGA----基于ZYNQ 7020实现定制化的EPICS通信系统
引言:前文我们降到了,使用alinx提供的sd卡,直接在上面编译即可。那么,如果我们的在FPGA侧有一些个性化的开发,那么生成的image.ub和boot.bin将于原sd卡中的不一致,我们应该如何坐呢? 补充知识点…...
读《暗时间》有感
读《暗时间》有感 反思与笔记 这本书还是我无意中使用 ima 给我写职业规划的时候给出的,由于有收藏的习惯,我就去找了这本书。当读到第一章暗时间的时候给了我很大的冲击,我本身就是一个想快速读完一本书的人,看到东西没有深入思…...
MIT关节电机相序校准
UVW三相相序判断 电机相序校正是确保多关节控制系统正常运行的重要步骤。在实际应用中,每个电机定子的三相线(W、U、V)的连接顺序可能存在差异,这是由于制造过程中的随机接线所致。不过,通过简单的校正方法,…...
Qwen2.5模型结构
self.lm_head nn.Linear(config.hidden_size, config.vocab_size, biasFalse) 这个是用来干嘛的 输出层,词汇投影层,将模型输出的隐藏状态向量映射回词表空间,用于预测下一个token # 预测 logits,未经过 softmax lm_logits self…...
2021-11-11 C++泰勒sin(x)以2步进乘方除以阶乘加减第N项
缘由c书本题,求解了,求解-编程语言-CSDN问答 int n 10, d 3, z -1; double x 2.5, xx x;while (n){xx (乘方(x, d) / 阶乘(d)) * z;d 2, --n, z * -1;}std::cout << xx << std::endl;...
【MySQL】C语言访问数据库
C语言访问数据库 一. Linux 安装 MySQL 动静态库二. 使用MySQL数据库1. 创建MySQL对象2. 连接MySQL数据库3. 释放MySQL对象4. SQL 语句操作1. 插入操作2. 修改操作3. 删除操作4. 查询操作 准备工作 use mysql; select user, host from user;# 创建本地连接的用户 create user c…...
dify 部署后docker 配置文件修改
1:修改 复制 ./dify/docker/.env.example ./dify/docker/.env 添加一下内容 # 启用自定义模型 CUSTOM_MODEL_ENABLEDtrue# 将OLLAMA_API_BASE_URL 改为宿主机的物理ip OLLAMA_API_BASE_URLhttp://192.168.72.8:11434# vllm 的 OPENAI的兼容 API 地址 CUSTOM_MODE…...
【神经网络与深度学习】VAE 和 GAN
这位大佬写的 VAE 的讲解很不错 VAE 和 GAN 的相同点和不同点 引言 VAE(变分自编码器)和 GAN(生成对抗网络)是深度学习中两种主要的生成模型,它们在数据生成任务中发挥着重要作用。虽然它们的目标相似,都…...
2-C#控件
2-控件 1.panel控件的使用 private void button3_Click(object sender, EventArgs e){Form2 my2 new Form2();my2.TopLevel false;this.panel1.Controls.Add(my2);my2.BringToFront();my2.Show();}private void button4_Click(object sender, EventArgs e){Form3 my3 new F…...
1.1.2 简化迭代器 yield return的使用
yield return 是一个用于简化迭代器(Iterator)实现的关键字组合。它的核心作用是让开发者能够以更简洁的方式定义一个按需生成序列的方法(生成器方法),而无需显式实现 IEnumerable 或 IEnumerator 接口。yield return …...
机器学习实操 第二部分 神经网路和深度学习 第14章 使用卷积神经网络进行深度计算机视觉
机器学习实操 第二部分 神经网路和深度学习 第14章 使用卷积神经网络进行深度计算机视觉 内容概要 第14章深入探讨了卷积神经网络(CNNs)及其在计算机视觉中的应用。CNNs受大脑视觉皮层的启发,通过局部感受野和权值共享机制,能够…...
电商双11美妆数据分析(2)
接下来用seaborn包给出每个店铺各个大类以及各个小类的销量销售额 关于性别 接下来考虑性别因素,了解各类产品在男性消费者中的销量占比 男士的销量基本来自于清洁类,其次是补水类。而这两类正是总销量中占比最高的两类。 非男士专用中,补水…...
数字康养新范式:七彩喜平台重构智慧养老生态的深度实践
在全球人口老龄化程度日益加深的当下,养老问题成为社会关注的焦点。 智慧养老作为一种创新的养老模式,借助现代信息技术,为提升老年人生活质量、缓解养老压力提供了新的思路与途径。 而当前中国 60 岁以上人口已达 2.8 亿,占总人…...
2D横板跳跃游戏笔记(查漏补缺ing...)
1.Compression(压缩质量):可以改为None,不压缩的效果最好,但占用内存 2.Filter Mode(过滤模式):可以选择Point(no filter) 3.Pixels Per Unit:是…...
c++中“”符号代表引用还是取内存地址?
c中,“&”符号有时代表引用,有时代表取地址符。 一、引用和取址 引用是一个已存在变量的别名,修改别名的值,原始变量的值也会改变;而取地址符则是得到一个指针,该指针指向变量的内存地址。 1&#x…...
AGV智能搬运机器人:富唯智能引领工业物流高效变革
在智能制造与工业4.0深度融合的今天,物流环节的高效与精准已成为企业核心竞争力的关键。富唯智能凭借其自主研发的AGV智能搬运机器人,以创新技术重塑工业物流标准,助力企业实现降本增效的跨越式发展。 一、技术突破:精准导航与智能…...
今年中国新能源汽车销量已破400万辆 大增42%
快科技5月7日消息,乘联分会公布了2025年4月新能源乘用车厂商批发销量数据。 纵观2025年以来,综合预估今年1-4月累计批发400万辆,同比增长42%。 根据中汽协发布的数据,2024年中国新能源汽车市场产销两旺,全年累计销量…...
广告屏蔽插件的内部细节EasyList 规则详解:为什么广告屏蔽不直接用 CSS/JS?(彩蛋)
广告屏蔽插件的内部细节:EasyList 规则详解;为什么广告屏蔽不直接用 CSS/JS屏蔽广告? 我们经常在浏览器中使用一些广告屏蔽插件(如 uBlock Origin、AdGuard、AdBlock Plus)已经成为许多用户的必备插件。 刚开…...
TCGA数据库临床亚型可用!贝叶斯聚类+特征网络分析,这篇 NC 提供的方法可以快速用起来了!
生信碱移 贝叶斯网络聚类 CANclust是一种基于贝叶斯的聚类方法,系统性地对基因突变、细胞遗传学信息和临床指标进行联合建模,用于多种模态数据的联合聚类分析,并识别在患者群体中反复出现的特征模式。 个体的遗传与环境背景决定其应对疾病的…...
好的软件系统
一个“好的软件系统”通常具有以下几个核心特征,简洁来说就是:“能用、好用、易维护、可扩展、安全可靠”。 一个好的软件系统,不只是“能跑起来”,而是“跑得稳、跑得快、跑得久,而且随时能换赛道还能继续跑 高内聚2.…...
某大型交通规划设计院转型实践:数智化破局复杂工程项目管理,实现高效人力资源一体化管理
随着中国经济的快速发展及基础设施建设的不断推进,交通规划设计行业正迎来新的机遇与挑战。作为行业的标杆企业,某大型交通规划设计院(以下简称G院)自1952年成立以来,始终致力于为公路、市政、建筑、园林规划等领域提供…...
格雷狼优化算法`GWO 通过模拟和优化一个信号处理问题来最大化特定频率下的功率
这段代码是一个Python程序,它使用了多个科学计算库,包括`random`、`numpy`、`matplotlib.pyplot`、`scipy.signal`和`scipy.signal.windows`。程序的主要目的是通过模拟和优化一个信号处理问题来最大化特定频率下的功率。 4. **定义类`class_model`**: - 这个类包含了信号…...
react中的用法——setDisabled dva dispatch effects
setDisabled 在react中,setDisabled通常是指通过状态管理来控制某个组件(如按钮、输入框等)的禁用状态。虽然react本身没有内置的setDisabled方法,但你可以使用useState钩子来实现类似的功能。以下是一个简单的示例,展…...