字符设备注册与注销

news2024/11/24 18:55:29

1、对于字符设备驱动而言,当驱动模块加载成功以后需要注册字符设备,同样,卸载驱动模 块的时候也需要注销掉字符设备。字符设备的注册和注销函数原型如下所示

static inline int register_chrdev(unsigned int major, const char *name,
                                    const struct file_operations *fops)
static inline void unregister_chrdev(unsigned int major, const char *name)

register_chrdev 函数用于注册字符设备,此函数一共有三个参数

major:主设备号,Linux 下每个设备都有一个设备号,设备号分为主设备号和次设备号两 部分,关于设备号后面会详细讲解。

name:设备名字,指向一串字符串。

fops:结构体 file_operations 类型指针,指向设备的操作函数集合变量。

unregister_chrdev 函数用户注销字符设备,此函数有两个参数

major:要注销的设备对应的主设备号。

name:要注销的设备对应的设备名。

2、一般字符设备的注册在驱动模块的入口函数 xxx_init 中进行,字符设备的注销在驱动模块 的出口函数 xxx_exit 中进行。

1 static struct file_operations test_fops;
2
3 /* 驱动入口函数 */
4 static int __init xxx_init(void)
5 {
6     /* 入口函数具体内容 */
7     int retvalue = 0;
8
9     /* 注册字符设备驱动 */
10     retvalue = register_chrdev(200, "chrtest", &test_fops);
11     if(retvalue < 0){
12     /* 字符设备注册失败,自行处理 */
13     }
14     return 0;
15 }
16
17 /* 驱动出口函数 */
18 static void __exit xxx_exit(void)
19 {
20     /* 注销字符设备驱动 */
21     unregister_chrdev(200, "chrtest");
22 }
23
24 /* 将上面两个函数指定为驱动的入口和出口函数 */
25 module_init(xxx_init);
26 module_exit(xxx_exit);

第 1 行,定义了一个 file_operations 结构体变量 test_fopstest_fops 就是设备的操作函数集 合,只是此时我们还没有初始化 test_fops 中的 open、release 等这些成员变量,所以这个操作函 数集合还是空的。

第 10 行,调用函数 register_chrdev 注册字符设备,主设备号为 200,设备名字为“chrtest”, 设备操作函数集合就是第 1 行定义的 test_fops。要注意的一点就是,选择没有被使用的主设备 号,输入命令“cat /proc/devices”可以查看当前已经被使用掉的设备号

图中可以列出当前系统中所有的字符设备和块设备,其中第 1 列就是设备对应 的主设备号。200 这个主设备号在我的开发板中并没有被使用,所以我这里就用了 200 这个主 设备号。 第 21 行,调用函数 unregister_chrdev 注销主设备号为 200 的这个设备。

3、实现设备的具体操作函数

file_operations 结构体就是设备的具体操作函数,我们定义了 file_operations结构体类型的变量test_fops,但是还没对其进行初始化,也就是初始化其中的open、 release、readwrite 等具体的设备操作函数。

能够对 chrtest 进行打开和关闭操作

设备打开和关闭是最基本的要求,几乎所有的设备都得提供打开和关闭的功能。因此我们 需要实现 file_operations 中的 open 和 release 这两个函数

对 chrtest 进行读写操作

假设 chrtest 这个设备控制着一段缓冲区(内存),应用程序需要通过 read 和 write 这两个函 数对 chrtest 的缓冲区进行读写操作。所以需要实现 file_operations 中的 read 和 write 这两个函 数。

1     /* 打开设备 */
2 static int chrtest_open(struct inode *inode, struct file *filp)
3 {
4     /* 用户实现具体功能 */
5     return 0;
6 }
7 
8     /* 从设备读取 */
9 static ssize_t chrtest_read(struct file *filp, char __user *buf, 
size_t cnt, loff_t *offt)
10 {
11     /* 用户实现具体功能 */
12     return 0;
13 }
14
15     /* 向设备写数据 */
16 static ssize_t chrtest_write(struct file *filp,const char __user *buf,
size_t cnt, loff_t *offt)
17 {
18     /* 用户实现具体功能 */
19     return 0;
20 }
21
22 /* 关闭/释放设备 */
23 static int chrtest_release(struct inode *inode, struct file *filp)
24 {
25     /* 用户实现具体功能 */
26     return 0;
27 }
28
29 static struct file_operations test_fops = {
30     .owner = THIS_MODULE, 
31     .open = chrtest_open,
32     .read = chrtest_read,
33     .write = chrtest_write,
34     .release = chrtest_release,
35 };
36
37 /* 驱动入口函数 */
38 static int __init xxx_init(void)
39 {
40     /* 入口函数具体内容 */
41     int retvalue = 0;
42
43     /* 注册字符设备驱动 */
44     retvalue = register_chrdev(200, "chrtest", &test_fops);
45     if(retvalue < 0){
46     /* 字符设备注册失败,自行处理 */
47     }
48     return 0;
49 }
50
51 /* 驱动出口函数 */
52 static void __exit xxx_exit(void)
53 {
54     /* 注销字符设备驱动 */
55     unregister_chrdev(200, "chrtest");
56 }
57
58 /* 将上面两个函数指定为驱动的入口和出口函数 */
59 module_init(xxx_init);
60 module_exit(xxx_exit);

我们编写了四个函数:chrtest_open、chrtest_read、chrtest_writechrtest_release。这四个函数就是 chrtest 设备的 open、read、write 和 release 操作函数。第 29 行~35 行初始化 test_fops 的 open、read、write 和 release 这四个成员变量

4、添加 LICENSE 和作者信息

最后我们需要在驱动中加入 LICENSE 信息和作者信息,其中 LICENSE 是必须添加的,否 则的话编译的时候会报错,作者信息可以添加也可以不添加。LICENSE 和作者信息的添加使用 如下两个函数:

MODULE_LICENSE() //添加模块 LICENSE 信息

MODULE_AUTHOR() //添加模块作者信息

结合上次示例代码  加入 LICENSE 和作者信息,完成以后的内容如下:

1 /* 打开设备 */
2 static int chrtest_open(struct inode *inode, struct file *filp)
3 {
4      /* 用户实现具体功能 */
5         return 0;
6 }
......
57
58 /* 将上面两个函数指定为驱动的入口和出口函数 */
59 module_init(xxx_init);
60 module_exit(xxx_exit);
61
62 MODULE_LICENSE("GPL");
63 MODULE_AUTHOR("hsj");

第 62 行,LICENSE 采用 GPL 协议。

第 63 行,添加作者名字。 至此,字符设备驱动开发的完整步骤就讲解完了,而且也编写好了一个完整的字符设备驱 动模板,以后字符设备驱动开发都可以在此模板上进行。

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

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

相关文章

虹科方案 | HK-Edgility系统随时随地保护您的远程工作

通过上次的文章&#xff0c;我们了解到虹科HK-Edgility软件系统《将云计算扩展到边缘》的解决方案。今天的文章&#xff0c;我们将带您了解虹科系统在远程工作的方案简介。 一、时代背景 在当今新的数字化工作空间中&#xff0c;员工需要从家中、远程办公室和旅途中访问公司业务…

作为团队管理者,如何获得团队成员的信任和认可?

作为团队管理者&#xff0c;获得团队成员的信任和认可是非常重要的。只有当团队成员信任你并认可你的领导能力&#xff0c;才能更好地协同工作&#xff0c;提高工作效率和完成团队目标。那么&#xff0c;如何才能获得团队成员的信任和认可呢&#xff1f;以下是一些实用的建议。…

全球首个天基蜂窝语音通话,打通了,这个重大新闻非常值得关注

4月25日&#xff0c;美国卫星通信初创公司——AST SpaceMobile&#xff0c;宣布打通了全球首个天基蜂窝语音通话。 对于卫星通信乃至整个通信行业来说&#xff0c;这是一个重大新闻&#xff0c;非常值得关注。 去年&#xff0c;我们还只是实现了手机和卫星之间的双向短消息通信…

柯桥学习商务英语的四个阶段

商务英语第一阶段   第一阶段也被称为“商务零基础”&#xff0c;这个课程主要针对零起点或长期没接触英语的学习者&#xff1b;有一定英语基础&#xff0c;想提高英语发音的学员。   从零入门&#xff0c;从ABC开始。通过对英语的初步了解与认识&#xff0c;最终使学员达…

用 Yjs + React 写一个支持协同的 TODO 应用

大家好&#xff0c;我是前端西瓜哥。 为了测试 Yjs 的协同能力&#xff0c;我实现了支持协同简单的 TODO 应用。 支持的功能 创建房间&#xff1b;新增、删除、完成、清空所有待办&#xff1b;撤销重做&#xff1b;显示其他用户的光标位置&#xff1b; 技术栈 列一下用到的…

多线程并发编程学习笔记11(小滴课堂)数据同步接口

中间表设计&#xff1a; 我们原来有一张学生表。 然后我们去设计中间表&#xff1a; 基础环境搭建&#xff1a; 既然是搭建环境那肯定要先从maven入手&#xff0c;引入依赖&#xff1a; 然后我们需要去配置我们的mybatis的xml文件。 同样中间表的数据库我们也要进行配置&#…

Python+opencv:图像修复

简介&#xff1a;OpenCV 是一个开源的计算机视觉库&#xff0c;它包含了许多图像处理和计算机视觉算法。使用 OpenCV 进行图像修复主要依赖于传统的图像处理技术。 OpenCV 图像修复方法及其原理&#xff1a; 1、去噪&#xff1a;图像去噪是消除图像中的噪声&#xff0c;提高图…

H3C路由器(通用)限速(命令行)配置方法

1 配置需求或说明 1.1 适用产品系列 本手册适用于如下产品&#xff1a;MSR 全系列路由器 1.2 配置需求及实现的效果 MSR路由器G0/0接口连接公网&#xff0c;G0/1接口连接内网&#xff0c;内网网关地址为MSR路由器VLAN1虚接口地址192.168.1.1/24&#xff0c;需要实现对内网I…

Python小姿势 - 如果你不会Python,不要紧,按照以下步骤操作即可:

如果你不会Python&#xff0c;不要紧&#xff0c;按照以下步骤操作即可&#xff1a; 在百度搜索“Python随机数”&#xff0c;找到第一个搜索结果&#xff1b;在搜索结果页面&#xff0c;随机点开一个链接&#xff1b;在新打开的页面&#xff0c;查看页面标题&#xff0c;作为你…

【郭东白架构课 模块二:创造价值】24|节点四:如何减少语义上的分歧?

你好&#xff0c;我是郭东白。上节课我们通过一个篇幅比较长的电商案例&#xff0c;详细展示了为什么在架构活动中会出现语义分歧。同时也描述了&#xff0c;架构师在统一语义这个环节中所要创造的真正价值是什么。即&#xff0c;看到不同角色之间语境的差异&#xff0c;然后通…

案例2:东方财富股吧文本分析----code模块封装命令行运行版

案例2&#xff1a;东方财富股吧文本分析----code模块封装命令行运行版 0. 先导语1.东方财富股吧文本信息爬取1.1 模块getGuBaNews.py的内容1.2 东方财富股吧文本信息爬取主运行文件run_main_getnews.py内容1.3 命令行运行 2.东方财富股吧文本信息分析2.1 模块gubaNewsAnalyse.p…

『python爬虫』11. xpath解析实战之获取csdn文章信息(保姆级图文)

目录 网页结构分析爬取思路得到所有的文章遍历每个文章得到其中的信息 实现代码总结 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 网页结构分析 我的csdn主页 https://blog.csdn.net/u011027547我们先找一篇文章…

AI 工具合辑盘点(八)持续更新 之 AI 面部生成工具和AI 角色生成工具

&#xff08;一&#xff09;AI 面部生成工具 需要一张真实人物的肖像画来用于你的营销材料&#xff1f;正在寻找具有特定面部特征的模特&#xff0c;但你的预算有限&#xff1f;正在创建你的买家人物&#xff0c;但不想从互联网上窃取图片&#xff1f; 如果是这样&#xff0c…

pytorch——损失函数之nn.L1Loss()和nn.SmoothL1Loss()

文章目录 【回归损失函数】L1&#xff08;MAE&#xff09;、L2&#xff08;MSE&#xff09;、Smooth L1 Loss详解1. L1 Loss&#xff08;Mean Absolute Error&#xff0c;MAE&#xff09;1.1 数学定义1.2 、使用场景与问题1.3 、如何使用 2. L2 Loss&#xff08;Mean Squared E…

[项目实战] 博客系统实现

水到渠成,冲呀冲呀 文章目录 1 准备工作1.1 在Idea创建一个Maven项目1.2 引入servlet,masql,jackson依赖1.3 准备web.xml文件 2. 数据库建表3. 封装DBUtil4. 创建实体类4.1 Blog类4.2 User类 5. 封装数据库的增删改查5.1 对于blog的操作5.1.1 增加操作5.1.2 根据blogId查询5.1 …

Notepad++配置C语言环境和C++环境

背景&#xff1a; Notepad是我们经常使用的编辑器&#xff0c;我们可以用它编译和运行各种类型的文档&#xff0c;其中就包括了C和C文档。但是编译和运行C或者C文档首先要配置编译环境&#xff0c;下面给大家分享一下如何在NotePad配置C/C编译环境。 工具&#xff1a; NoteP…

在全志V851S开发板上进行屏幕触摸适配

1.修改屏幕驱动 从ft6236 &#xff08;删掉&#xff0c;不要保留&#xff09;&#xff0c;改为下面的 路径&#xff1a;/home/wells/tina-v853-open/tina-v853-open/device/config/chips/v851s/configs/lizard/board.dts&#xff08;注意路径&#xff0c;要设置为自己的实际路…

docker-compose部署flume

一、docker-compose部署 1. 依赖的服务/组件 java8flume 1.9.0 2. 下载离线安装包 jdk8https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gzflume 1.9.0https://mirrors.tuna.tsinghua.edu.cn/apache/flume/1.9.0/apache-flume-1.9.0-bin.tar.gzs…

【Python入门篇】——Python基础语法(标识符与运算符)

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; Python入门&#xff0c;本专栏主要内容为Python的基础语法&#xff0c;Python中的选择循环语句…

鸿蒙Hi3861学习六-Huawei LiteOS(软件定时器)

一、简介 软件定时器&#xff0c;是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick时钟计数值后&#xff0c;会触发用户定义的回调函数。定时精度与系统Tick时钟周期有关。 硬件定时器受硬件的限制&#xff0c;数量上不足以满足用户的实际需求。因此&#xff0…