Linux驱动开发——(十)MISC设备驱动

目录

一、MISC驱动介绍

1.1 miscdevice结构体

1.2 misc_register函数

1.3 misc_deregister函数

二、驱动代码

2.1 框架代码流程

2.2 完整框架代码


一、MISC驱动介绍

MISC驱动(杂项驱动),当板子上的某些外设无法进行分类的时候就可以使用MISC驱动。

MISC驱动最简单的字符设备驱动,通常嵌套在platform总线驱动中,实现复杂的驱动。随着Linux字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号,MISC设备驱动用于解决此问题。

所有的MISC设备驱动的主设备号为10,不同的设备使用不同的从设备号。

1.1 miscdevice结构体

MISC设备会自动创建cdev,不需要手动创建,因此采用MISC设备驱动可以简化字符设备驱动的编写。miscdevice结构体定义在include/linux/miscdevice.h中:

struct miscdevice { 
    int minor; /* 子设备号 */ 
    const char *name; /* 设备名字 */ 
    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设备以后需要设置minor、name和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 MISC_DYNAMIC_MINOR 255

name:此MISC设备名字,当此设备注册成功以后就会在/dev目录下生成一个名为name的设备文件。

fops:字符设备的操作集合,MISC设备驱动需要使用用户提供的fops操作集合。

1.2 misc_register函数

当设置好miscdevice结构体后需要使用misc_register函数向系统中注册一个MISC设备

int misc_register(struct miscdevice * misc)

misc:要注册的MISC设备。
返回值:负数即失败;0即成功。

使用misc_register函数可以完成以下代码功能:

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

1.3 misc_deregister函数

需要卸载设备驱动模块时调用misc_deregister函数注销MISC设备

int misc_deregister(struct miscdevice *misc) 

misc:要注销 MISC设备。
返回值:负数即失败;0即成功。

使用misc_deregister函数可以完成以下代码功能:

cdev_del(); /* 删除cdev */ 
unregister_chrdev_region(); /* 注销设备号 */ 
device_destroy(); /* 删除设备 */ 
class_destroy(); /* 删除类 */

二、驱动代码

2.1 框架代码流程

先定义宏:

#define XXX_NAME		"miscxxx"	/* 名字 	*/
#define XXX_MINOR		144			/* 子设备号 */

再完善fops,然后将minor、namefops这三个成员变量设置进miscdevice结构体中:

static struct file_operations xxx_fops = { 
    .owner = THIS_MODULE,
};

static struct miscdevice xxx_miscdev = { 
    .minor = XXX_MINOR, 
    .name = XXX_NAME, 
    .fops = &xxx_fops, 
};

在probe函数中注册misc设备驱动

static int miscxxx_probe(struct platform_device *dev) {
    int ret = 0;
    /* 注册misc设备驱动 */ 
    ret = misc_register(&xxx_miscdev); 
    if(ret < 0){ 
        printk("misc device register failed!\r\n"); 
        return -EFAULT; 
    } 
    return 0; 
}

在remove函数中注销misc设备驱动

static int miscxxx_remove(struct platform_device *dev) 
    /* 注销misc设备驱动 */ 
    misc_deregister(&xxx_miscdev); 
    return 0; 
}

2.2 完整框架代码

如下:

#define XXX_NAME		"miscxxx"	/* 名字 	*/
#define XXX_MINOR		144			/* 子设备号 */


static struct file_operations xxx_fops = { 
    .owner = THIS_MODULE,
};

static struct miscdevice xxx_miscdev = { 
    .minor = XXX_MINOR, 
    .name = XXX_NAME, 
    .fops = &xxx_fops, 
};

static int miscxxx_probe(struct platform_device *dev) {
    int ret = 0;
    /* 注册misc设备驱动 */ 
    ret = misc_register(&xxx_miscdev); 
    if(ret < 0){ 
        printk("misc device register failed!\r\n"); 
        return -EFAULT; 
    } 
    return 0; 
}

static int miscxxx_remove(struct platform_device *dev) 
    /* 注销misc设备驱动 */ 
    misc_deregister(&xxx_miscdev); 
    return 0; 
}


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux 进程】 自定义shell

目录 关于shell 1.打印提示符&&获取用户命令字符​编辑 2.分割字符串 3.检查是否为内建命令 cd命令 export命令 echo命令 1.输出最后一个执行的命令的状态退出码&#xff08;返回码&#xff09; 2.输出指定环境变量 4.执行外部命令 关于shell Shell 是计算机操…

C语言数组介绍

文章目录 一、数组的概念二、一维数组1.一维数组的创建2.一维数组的初始化3.数组的类型4.一维数组的使用5.一维数组在内存中的存储6.sizeof计算数组元素个数 三、二维数组1.二维数组的概念2.二维数组的创建3.二维数组的初始化4.二维数组的使用5.二维数组的输入和输出6.二维数组…

【教学类-50-09】20240505“数一数”图片样式09:数一数(几何图案——透明颜色重叠+纯黑边框+黑框粗细)

背景需求&#xff1a; 【教学类-50-03】20240408“数一数”图片样式03&#xff1a;透明图形与边框不相交&#xff0c;透明图形和其他透明图形重叠-CSDN博客文章浏览阅读867次&#xff0c;点赞28次&#xff0c;收藏25次。【教学类-50-03】20240408“数一数”图片样式03&#xf…

银行ETL-监管报送

1104报表 1104报表主要包括&#xff1a;资产负债&#xff0c;表外业务、流动性风险、贷款质量、投向行业和地区、重点客户等。 1104报表分类 普通报表、机构特色类报表。 反洗钱 大额交易、可疑交易。标签分类&#xff1a;疑似犯罪、疑似毒品、疑似传销。 反洗钱—接口报…

tomcat+maven+java+mysql图书管理系统2-完善项目结构,添加相关依赖

1.创建java目录 接着选择java&#xff0c;回车&#xff0c;则创建成功&#xff0c;成功后在左侧栏能看见 2.修改pom.xml文件,(添加依赖) <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi…

pandas读取文件导致jupyter内核崩溃如何解决

读取execl文件出现以下问题: str_name "D:\\cao_use\\2017_2021(new).xlsx" train_df pd.read_excel(str_name, usecols[0])崩溃的指示图如下所示: bug原因:读入的文件太大&#xff0c;所需时间过长&#xff0c;在读取的过程中&#xff0c;使用中断按钮暂停会直…

mac监听 linux服务器可视化(Grafana+Promethus+Node_exporter)

Grafana和promethus(普罗米修斯)的安装和使用 监控系统的Prometheus类似于一个注册中心&#xff0c;我们可以只需要配置一个Prometheus,而在其他服务器&#xff0c;只需要安装node_exporter,它们的数据流转就是通过exporter采集数据信息&#xff0c;然后告诉prometheus它的位置…

AI视频教程下载:用 ChatGPT 和 WordPress 创建赚钱网站

您是否有兴趣开设网站&#xff08;博客&#xff09;&#xff0c;但不知道从何入手&#xff1f; 或者您已经开设了网站&#xff08;博客&#xff09;&#xff0c;但难以从中获利&#xff1f; 别找啦&#xff01; 本课程旨在教授您使用 WordPress 创建成功盈利网站&#xff08;博…

OpenCV(五) —— 人脸识别模型训练与 Windows 下的人脸识别

本文主要内容&#xff1a; 如何训练 OpenCV 的人脸识别模型如何在 Windows 下利用 OpenCV 进行人脸识别 1、概述 人脸识别需要人脸模型&#xff08;特征集合&#xff09;的支持&#xff0c;人脸定位的速度与准确度取决于模型。 OpenCV 提供了已经训练好的模型&#xff0c;无…

【莫比乌斯变换-04】求解莫比乌斯变换系数

求解莫比乌斯变换系数 文章目录 一、说明二、如何确定双线性变换系数2.1 变换基本形式2.2 通过三点确定 三、一般情况的变换3.1 最简单的情况&#xff1a;无穷大3.2 处理无穷大 四、Python 代码 一、说明 上一篇文章是对双线性变换的视觉介绍&#xff0c;又名莫比乌斯变换或分…

ThreeJS:补间动画与Tween.JS

补间动画 补间动画指的是做FLASH动画时&#xff0c;在两个关键帧中间需要做“补间动画”&#xff0c;才能实现图画的运动&#xff1b;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。 ——摘自《百度百科&#xff1a;补间动画_百度百科》 Tween.js Tween.js…

Python-VBA函数之旅-oct函数

目录 一、oct函数的常见应用场景 二、oct函数使用注意事项 三、如何用好oct函数&#xff1f; 1、oct函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;神奇夜光杯-CSDN博客 一、oct函数的常见应用场景 oc…

W801学习笔记十七:古诗学习应用——上

硬件驱动以及软件架构大体上已经完成&#xff0c;尚存一些遗漏之处&#xff0c;后续会寻找合适的时机进行补充。自此章起&#xff0c;将正式迈入软件应用阶段&#xff0c;尤其是游戏开发领域。 关于第一个应用&#xff0c;此前已有一些构想&#xff1a; 其一&#xff0c;随机…

IO流-其他流:数据流,序列化流

import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream;public class DataOutputStream1 {public static void main(String[] args) {//创建一个数据输出流包装一个低级的字节输出流try (DataOutputStream dosnew DataOutp…

9.3.k8s的控制器资源(deployment部署控制器)

目录 一、deployment部署控制器概念 二、deployment资源的清单编写 三、小结 功能 使用场景 原理 四、deployment实现升级和回滚 1.编辑deployment资源清单&#xff08;v1版本&#xff09; 2.创建service资源用于访问 ​编辑 3.修改deploy清单中pod镜像版本为V2 4…

「C/C++ 01」scanf()与回车滞留问题

目录 〇、scanf()接收用户输入的流程 一、回车的缓冲区滞留问题是什么&#xff1f; 二、为什么&#xff1f; 三、四个解决方法&#xff1a; 1. 在前面的scanf()中加上\n 2. 在scanf("%c")中添加空格 3. 使用getchar()来吸收回车 4. 使用fflush()清空缓冲区 〇、scan…

2.spring security 简单入门

创建springboot 项目&#xff0c;引入spring security坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--spring security坐标--><dependency&g…

leecode每日一练

我一开始的思路也是dp&#xff0c;但是转移方程想错了&#xff0c;这个题目转移方程应该是dp[i] max(dp[i-2]nums[i],dp[i-1]) class Solution { public:int rob(vector<int>& nums) {int len nums.size();vector<int> dp(len);int ans 0;if(len>1)dp[0]…

IoTDB 入门教程 基础篇①——时序数据库为什么选IoTDB ?

文章目录 一、前文二、性能排行第一三、完全开源四、数据文件TsFile五、乱序数据高写入六、其他七、参考 一、前文 IoTDB入门教程——导读 关注博主的同学都知道&#xff0c;博主在物联网领域深耕多年。 时序数据库&#xff0c;博主已经用过很多&#xff0c;从最早的InfluxDB&a…

《Fundamentals of Power Electronics》——脉宽调制器建模

下图给出了一个简单脉宽调制器电路的原理图。 脉宽调制器电路产生一个用于指令转换器功率管导通和关断的逻辑信号δ(t)。该逻辑信号δ(t)是周期性的&#xff0c;其频率为fs&#xff0c;占空比为d(t)。脉宽调制器的输入是一个模拟控制信号vc(t)。脉宽调制器的作用是产生一个与模…
最新文章