十四、(正点原子)Linux MISC驱动

        misc 的意思是混合、杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动。 MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 platform 总线驱动中,实现复杂的驱动。

一、MISC设备驱动

        随着 Linux字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号。所以在MISC驱动中所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。
        MISC 设备会自动创建 cdev,不需要像我们以前那样手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。

        在MISC中,使用struct miscdevice结构体来表示一个设备,我们需要向 Linux 注册一个 struct miscdevice 设备,内容如下:

定义在文件 include/linux/miscdevice.h 中struct miscdevice  {int minor;                             /* 次设备号 */const char *name;                      /* MISC设备名字 */const struct file_operations *fops;    /* 设备操作集合 */struct list_head list;struct device *parent;struct device *this_device;const struct attribute_group **groups;const char *nodename;umode_t mode;
};

         定义一个 MISC 设备(struct miscdevice 类型)以后我们需要设置 minorname fops 这三个成员变量。 minor 表示子设备号, MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号, Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号如下所示:

定义在include/linux/miscdevice.h 文件中#define PSMOUSE_MINOR		    1
#define MS_BUSMOUSE_MINOR	    2	    /* unused */
#define ATIXL_BUSMOUSE_MINOR	3	    /* unused *//*#define AMIGAMOUSE_MINOR	    4	    FIXME OBSOLETE */#define ATARIMOUSE_MINOR	    5	    /* unused */
#define SUN_MOUSE_MINOR		    6	    /* unused */
#define APOLLO_MOUSE_MINOR	    7	    /* unused */
#define PC110PAD_MINOR		    9	    /* unused *//*#define ADB_MOUSE_MINOR	    10	FIXME OBSOLETE */#define WATCHDOG_MINOR		    130	    /* Watchdog timer     */
#define TEMP_MINOR		        131	    /* Temperature Sensor */
#define RTC_MINOR		        135
#define EFI_RTC_MINOR		    136	    /* EFI Time services */
#define VHCI_MINOR		        137
#define SUN_OPENPROM_MINOR	    139
#define DMAPI_MINOR		        140	    /* unused */
#define NVRAM_MINOR		        144
#define SGI_MMTIMER		        153
#define STORE_QUEUE_MINOR	    155	    /* unused */
#define I2O_MINOR		        166
。。。
#define MISC_DYNAMIC_MINOR	    255    /* 动态自己分配 */

        我们在使用的时候可以从这些预定义的子设备号中挑选一个,当然也可以自己定义,只要这个子设备号没有被其他设备使用接口。当设置为255时,内核自动动态分配次设备号。

        name 就是此 MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为 name的设备文件。 fops 就是字符设备的操作集合, MISC 设备驱动最终是需要使用用户提供的 fops操作集合。

        当设置好 struct miscdevice 以后就需要使用 misc_register 函数向系统中注册一个 MISC 设备,此函数原型如下:

定义在include/linux/miscdevice.h 文件中extern int misc_register(struct miscdevice *misc);

        misc:要注册的MISC设备。 

        返回值:负数,失败;0,成功。

        以前创建字符设备时,需要调用一堆的函数去注册设备号,初始化字符设备,添加字符设备等等步骤如下所示:

传统的创建设备过程alloc_chrdev_region();       /* 申请设备号 */
cdev_init();                 /* 初始化 cdev */
cdev_add();                  /* 添加 cdev */
class_create();              /* 创建类 */
device_create();             /* 创建设备 */

        但是在MISC设备驱动中,其实也是一个字符设备,使用misc_register 函数就能够自动完成以前字符设备创建的功能。同理,在注销字符设备时候我们也需要调用一堆函数将前面创建的一些结构体给释放掉比如:


/* 注销设备号 */
unregister_chrdev_region(dtsled.devid, DTSLED_CNT);/* 注销LED字符设备 */
cdev_del(&dtsled.cdev);/* 删除设备 */
device_destroy(dtsled.class, dtsled.devid);/* 删除类 */
class_destroy(dtsled.class);

        当我们使用的时MISC设备时,就只需要调用 misc_deregister 函数就可以注销设备驱动,函数原型如下:

定义在include/linux/miscdevice.h 文件中extern int misc_deregister(struct miscdevice *misc);

        misc:要注销的MISC设备。

        返回值:负数,失败;0,成功。

二、MISC设备驱动示例代码

        


/* 设备操作函数 */
struct file_operations xxx_fops = {.owner = THIS_MODULE,
};/* MISC 设备结构体 */
struct miscdevice xxx_miscdev = {.minor = 255,    /* 前面有定义 */.name = "xxx",.fops = &xxx_fops,
};/* flatform 驱动的 probe 函数,当驱动与设备匹配以后此函数就会执行 */
int xxx_probe(struct platform_device *dev)
{。。。。misc_register(&xxx_miscdev);return 0;
}/* remove函数,移除 platform 驱动的时候此函数会执行 */
int xxx_remove(struct platform_device *dev)
{。。。/* 注销 misc 设备驱动 */misc_deregister(&xxx_miscdev);return 0;
}/* 匹配列表 */
const struct of_device_id beep_of_match[] = {{ .compatible = "xxx" },     /* 要与设备树的compatible属性一致 */{ /* Sentinel */ }
};/* 驱动设备结构体 */
struct platform_driver xxx_driver = {.driver = {.name = "xxx",                  /* 驱动名字 */.of_match_table = xxx_of_match,  /* 设备树匹配表 */},.probe = xxx_probe,.remove = xxx_remove,};/* 驱动入口函数 */
static int __init xxx_init(void)
{return platform_driver_register(&xxx_driver);
}/* 驱动出口函数 */
static void __exit xxx_exit(void)
{platform_driver_unregister(&xxx_driver);
}module_init(xxx_init);
module_exit(xxx_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangxueguo");

        当我们驱动加载成功后,在/sys/class/misc这个目录下可以看到一个struct platform_driver->driver->name名字的设备,如果MISC设备与驱动像匹配以后,就会在dev/下生成的一个struct miscdevice->name设备驱动文件。

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

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

相关文章

IDEA启动Web项目总是提示端口占用

文章目录 IDEA启动Web项目总是提示端口占用一、前言1.场景2.环境 二、正文1.场景一:真端口占用2. 场景二:假端口占用 IDEA启动Web项目总是提示端口占用 一、前言 1.场景 IDEA启动Web项目总是提示端口占用: 确实是端口被占用,比如:没有正常…

clion中建立c文件工程,读取或创建sqlite3数据库文件

1.首先前往SQLite官网下载sqlite3所需文件 SQLite Download Page 2.解压文件,将其中的sqlite3.c和sqlite3.h拷贝到你对应的文件工程中 3.修改CMakeLists.txt文件,添加编译选项及连接文件 4.运行代码及查询数据库文件

【NLP自然语言处理】基于BERT实现文本情感分类

Bert概述 BERT(Bidirectional Encoder Representations from Transformers)是一种深度学习模型,用于自然语言处理(NLP)任务。BERT的核心是由一种强大的神经网络架构——Transformer驱动的。这种架构包含了一种称为自注…

【Mamba】Mamba的部署

ubuntu系统安装11.6版本的cuda 可以参考这两篇博客 ubuntu22.04多版本安装cuda及快速切换(cuda11.1和11.8)_ubuntu调整cuda版本 【Linux】在一台机器上同时安装多个版本的CUDA(切换CUDA版本)_linux安装多个cuda 安装CUDA https…

js原生ajax请求

以下是使用 JavaScript 原生的 XMLHttpRequest 对象进行 ajax 请求的示例代码: function ajaxRequest(method, url, data, callback) {var xhr new XMLHttpRequest();xhr.open(method, url, true);if (method POST) {xhr.setRequestHeader(Content-Type, applica…

安全与认证:在Symfony中实现用户登录和权限管理

安全与认证:在Symfony中实现用户登录和权限管理 目录 简介Symfony 安全组件概述用户登录实现 配置安全系统创建用户实体配置用户提供者创建登录表单 权限管理实现 角色与权限配置控制器中的权限检查安全注解的使用 示例项目 项目结构示例代码 总结 1. 简介 在现…

【React打卡学习第一天】

React入门 一、简介二、基本使用1.引入相关js库2.babel.js的作用 二、创建虚拟DOM三、JSX(JavaScript XML)1.本质2.作用3.基本语法规则定义虚拟DOM时,不要写引号。标签中混入JS表达式时要用{}。样式的类名指定不要用class,要用className.内联…

掌握未来:深度解析Xcode Cloud服务的高效使用

掌握未来:深度解析Xcode Cloud服务的高效使用 随着软件开发的不断进步,开发者们越来越需要一个能够提升效率、降低成本的工具。苹果公司推出的Xcode Cloud服务正是为了满足这一需求。本文将详细解析如何使用Xcode Cloud服务,并通过实际代码示…

大语言模型系列:Transformer

在自然语言处理(NLP)领域,Transformer模型自2017年由Vaswani等人在论文《Attention Is All You Need》中提出以来,已成为最具影响力的技术之一。这种模型设计的核心是自注意力机制,它允许模型在处理序列数据时&#xf…

solidity基础语法(以太坊solidity合约)

solidity基础语法(以太坊solidity合约) 1-值类型和取值范围2-引用类型3-引用类型高阶4-固定数组和动态数组 1-值类型和取值范围 https://learnblockchain.cn/docs/solidity/introduction-to-smart-contracts.html#subcurrency https://learnblockchain…

Nest.js 实战 (二):如何使用 Prisma 和连接 PostgreSQL 数据库

什么是 Prisma? Prisma 是一个开源的下一代 ORM。它包含了以下部分: Prisma Client: 自动生成、类型安全的查询构建器,用于 Node.js 和 TypeScriptPrisma Migrate: 数据迁移系统Prisma Studio: 查询和编辑数据库中数据的图形化界面 Prisma 客户端可以…

JAVA23种设计模式简介

设计模式 设计模式的类型 创建型模式 隐藏了创建对象的过程,通过逻辑方法进行创建对象,而不是通过new关键字创建对象。 工厂方法模式 定义接口或一个抽象的工厂类,让它实现类(工厂)来决定创建哪一个实例对象。根据每…

Unity3D中ProtoBuf的编译与使用详解

引言 Unity3D作为当今最流行的游戏开发引擎之一,支持多种编程语言,特别是C#,并提供了丰富的工具集来创建高质量的2D和3D游戏。在游戏开发中,数据的序列化和反序列化是至关重要的一环,它们影响着游戏的性能、网络通信的…

idea 运行异常 gradle 项目

运行异常日志如: > Process command C:/Program Files/Java/jdk-1.8/bin/java.exe finished with non-zero exit value 1* Try: Run with --info or --debug option to get more log output. Run with --scan to get full insights.* Exception is: org.gradle.…

React、Vue的password输入框组件,如何关闭自动填充?

有时候我们的表单使用了一个password组件,这时候每次打开新建,都会自动获取浏览器缓存的密码,但是它的上一个input输入框并不是用户名,这时候我们希望我们的表单,每次点开的时候密码是空的,让用户自动输入&…

Llama - 量化

本文翻译整理自: https://llama.meta.com/docs/how-to-guides/quantization/ 文章目录 PyTorch中支持的量化模式使用 TorchAO 进行 Pytorch量化HF支持的量化QuantoAQLMAWQAutoGPTQBitsAndBytes 量化是机器学习中使用的一种技术,用于减少模型的计算和内存…

PyTorch张量数值计算

文章目录 1、张量基本运算2、阿达玛积3、点积运算4、指定运算设备⭐5、解决在GPU运行PyTorch的问题 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发、数据结构和算法&am…

【设计模式】【创建型模式】【02工厂模式】

系列文章 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录 系…

【安全】系统安全设计规范(DOC完整版)

1.1安全建设原则 1.2 安全管理体系 1.3 安全管理规范 1.4 数据安全保障措施 1.4.1 数据库安全保障 1.4.2 操作系统安全保障 1.4.3 病毒防治 1.5安全保障措施 1.5.1实名认证保障 1.5.2 接口安全保障 1.5.3 加密传输保障 1.5.4终端安全保障 软件资料清单列表部分文档&…

只需点击几下即可从Mac恢复已删除或丢失的文件

当无聊袭来时,您的 Mac 不是一个有趣的朋友吗?它确实是您“全天候”的主力军,可以兼顾日常工作。而且,它存储了大量关键文件,包括视频、图片、歌曲、文档等等。 如果丢失此数据会怎样?你的“数字生活”可能…