石家庄电力设计公司/seo网站推广批发
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT、4G模块、CAN、RS485等接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩,物联网,工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用、
【公众号】迅为电子
【粉丝群】258811263(加群获取驱动文档+例程)
第三部分 Linux驱动基础
第三十九章 Linux MISC驱动
本章导读
Linux MISC驱动是最简单的字符设备驱动,学习MISC驱动将会为学习字符设备驱动奠定基础。
39.1 章节讲解了misc设备驱动的基本概念及函数使用方法
39.2 章节讲解了编写最简单的杂项设备驱动,并将其编译为驱动模块,在iTOP-3399开发板上运行测试。
本章内容对应视频讲解链接(在线观看):
杂项设备驱动讲解 → 杂项设备驱动讲解_哔哩哔哩_bilibili
编写一个杂项设备驱动 → https://www.bilibili.com/video/BV1Vy4y1B7ta?p=10
程序源码在网盘资料“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\2.驱动程序例程\02-杂项设备驱动实验”路径下。
39.1 misc设备驱动简介
本章节我们讲解杂项设备驱动,那么杂项设备驱动是属于我们linux三大设备驱动的哪一项呢?由于linux驱动倾向于分层设计,所以每个具体的设备都可以找到它归属的类型,从而可以套到它相应的架构里面去,我们只需要实现它最底层的那部分。但是也有部分字符设备,确实不知道它属于哪种类型,我们一般推荐大家采用miscdevice的框架结构。misc 的意思是混合的杂项的,所以 misc 设备驱动也叫做杂项设备驱动,当我们板子上的某个设备没有办法分类时,就可以用 misc 设备驱动。它的注册跟使用比较的简单,所以比较适用于功能简单的设备。正因为简单,所以它通常嵌套在 platform 总线驱动中,配合总线驱动达到更复杂,多功能的效果。杂项设备是字符设备的一种,杂项设备可以自动生成设备节点。
在学习misc设备驱动之前,先来了解几个基础概念。
概念1设备节点
我们可以启动我们的开发板,进入到dev目录下,dev目录下全部都是生成的设备节点,如下图所示:
我们的系统里面有很多杂项设备。我们可以输入以下命令来查看,如下图所示:
cat /proc/misc
概念2 杂项设备的优点
杂项设备除了比字符设备代码简单,还有别的区别吗?所有的 misc 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。主设设备号相同就可以节省内核的资源,在内核中大概可以找到200多处使用miscdevice框架结构的驱动。
概念3主设备号和次设备号的概念
设备号包含主设备号和次设备号,设备号是计算机识别设备的一种方式,主设备号相同的就被视为同一类设备,主设备号在Linux系统里面是唯一的,次设备号不一定唯一。主设备号可以比做成电话号码的区号。比如北京的区号是010,次设备号可以比作成电话号码。
主设备号可以通过以下命令来查看,前面的数字就是主设备号,如下图所示:
cat /proc/devices
misc 设备用 miscdevice 结构体表示,miscdevice结构体的定义在内核源码具体定义/home/topeet/linux/linux-imx/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 设备的 miscdevice 结构体时,需要我们指定 minor、name 和 fops 这三个成员变量。minor 表示次设备号,需要用户设置,在 Linux 内核中有一些预定义的 misc 设备的次设备号,定义在/home/topeet/linux/linux-imx/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 设备的操作集合。
当创建好miscdevice 结构体后,使用 misc_register 函数向系统中注册一个misc设备,函数原型如下:
函数 | int misc_register(struct miscdevice * misc) |
参数 misc | 之前创建好的 miscdevice 结构体 |
返回值 | 成功返回 0,失败返回负数。 |
我们设置子设备号时要注意不要重复使用其他设备的子设备号。可以从这些预定义的子设备号中选择
一个,也可以自定义。
name 就是这个 misc 设备的名字,当设备注册成功后,会在/dev 目录下自动生成一个名为 name 的设备文件。fops 就是这个 misc 设备的操作集合。
函数 | int misc_deregister(struct miscdevice *misc) |
参数misc | 要注销的 miscdevice 结构体。 |
返回值 | 无 |
在miscdevice结构体的第四行,它指向了一个file_operation的结构体。file_operations文件操作集在定义在include/linux/fs.h下面,如下图所示。
file_operations中的成员函数实际是由drivers/char/misc.c中misc驱动核心层的misc_fops成员函数间接调用的。file_operations结构体里面的结构体成员都对应一个调用。简单介绍一下其中比较常用的函数:
llseek()函数用来修改一个文件的当前的读写位置,并将新位置返回。
read()函数用来从设备中读取数据,成功时返回读取到的字节数,出错返回一个负值。
write()函数用来向设备发送数据,成功时返回该函数写入的字节数。
poll()函数用于查询设备是否可以进行非阻塞读写。
unlock_ioctl()函数提供设备相关控制命令的实现。
mmap()函数将设备内存映射到进程的虚拟地址空间中。
open()函数用于打开设备文件。
release()函数用于关闭设备文件。
注册杂项设备有一个通用的思路和方法,这里给大家总结为三个步骤:
- 填充miscdevice这个结构体
- 填充file_operations这个结构体
- 注册杂项设备并生生成设备节点。
39.2 编写实验程序
通过39.1章节的学习,我们已经把杂项设备的基本概念搞懂了,在本实验中,使用 misc 设备驱动的方式来编写最简单的杂项设备的驱动。
39.2.1 编写驱动例程
首先我们回想一下注册杂项设备的三大流程,我们在Windows上面新建misc.c文件,并用sourceinsight打开。我们可以将上次编写的helloworld.c里面的代码拷贝到misc.c文件,并修改为如下图所示:
添加头文件
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>
填充miscdevice结构体
struct miscdevice misc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "hello_misc",
.fops = &misc_fops,
};
上述代码第2行的minor为MISC_DYNAMIC_MINOR,miscdevice核心层会自动找一个空闲的次设备号,否则用minor指定的次设备号。上述代码第3行name是设备的名称,我们自定义为"hello_misc"
填充file_operations结构体
struct file_operations misc_fops={
.owner = THIS_MODULE
};
THIS_MODULE宏是什么意思呢?它在include/linux/module.h里的定义是
#define THIS_MODULE (&__this_module)
它是一个struct module变量,代表当前模块,可以通过THIS_MODULE宏来引用模块的struct module结构,比如使用THIS_MODULE->state可以获得当前模块的状态。这个owner指针指向的就是你的模块。
注册杂项设备并生成设备节点
在misc_init()函数中填充misc_register()函数注册杂项设备,并判断杂项设备是否注册成功。
static int misc_init(void){int ret;ret = misc_register(&misc_dev); //注册杂项设备if(ret<0) //判断杂项设备是否注册成功{printk("misc registe is error \n"); //打印杂项设备注册失败}printk("misc registe is succeed \n"); //打印杂项设备注册成功return 0;
}
在misc_exit()函数中填充misc_deregister()函数注销杂项设备。static void misc_exit(void){misc_deregister(&misc_dev); //注销杂项设备printk("misc gooodbye! \n"); //打印杂项设备注销成功
}
完整的代码如下图所示:
/** @Descripttion: 最简单的杂项设备驱动* @version: 1.0* @Author: topeet*/
#include <linux/init.h> //初始化头文件
#include <linux/module.h> //最基本的文件,支持动态添加和卸载模块。
#include <linux/miscdevice.h> /*注册杂项设备头文件*/
#include <linux/fs.h> /*注册设备节点的文件结构体*/
struct file_operations misc_fops = { //文件操作集.owner = THIS_MODULE};
struct miscdevice misc_dev = {//杂项设备结构体.minor = MISC_DYNAMIC_MINOR, //动态申请的次设备号.name = "hello_misc", //杂项设备名字是hello_misc.fops = &misc_fops, //文件操作集};
static int misc_init(void)
{ //在初始化函数中注册杂项设备int ret;ret = misc_register(&misc_dev);if (ret < 0){printk("misc registe is error \n");}printk("misc registe is succeed \n");return 0;
}
static void misc_exit(void)
{ //在卸载函数中注销杂项设备misc_deregister(&misc_dev);printk(" misc gooodbye! \n");
}
module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");
现在最简单的杂项设备的驱动就写完了,那么接下来我们可以把这个驱动编译一下,然后放到我们的开发板上面运行。我们编译驱动,可以将它编译进内核里面,也可以将它编译成模块。
39.2.2 编译驱动程序
这里我们以iTOP-i.MX8MM开发板为例,将杂项设备驱动编译成模块,请参考本手册第三十七章 Linux内核模块。我们将misc.c文件拷贝到Ubuntu的/home/topeet/imx8m/02目录下。将上次编译helloworld的Makefile文件和build.sh脚本拷贝到misc.c同级目录下,修改Makefile为:
obj-m += misc.o
KDIR:=/home/topeet/linux/linux-imx
PWD?=$(shell pwd)
all:make -C $(KDIR) M=$(PWD) modules
clean:make -C $(KDIR) M=$(PWD) clean
文件如下图所示:
驱动编译成功生成了ko文件,如下图所示:
39.2.3 运行测试
启动iTOP-iMX8MM开发板,我们通过nfs挂载共享文件目录,我们进入到共享目录,加载驱动模块如图所示:
insmod misc.ko
驱动加载成功后,输入以下命令,查看注册的设备节点是否存在,如下图所示,设备节点存在。
ls /dev/h*
我们输入以下命令拆卸驱动模块,如下图所示:
rmmod misc
那么,现在最简单的杂项设备已经完成了。
相关文章:

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十九章 Linux MISC驱动
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...

基于MobileNetv2的垃圾分类函数式自动微分-昇思25天打卡
基于MobileNetv2的垃圾分类 本文档主要介绍垃圾分类代码开发的方法。通过读取本地图像数据作为输入,对图像中的垃圾物体进行检测,并且将检测结果图片保存到文件中。 1、实验目的 了解熟悉垃圾分类应用代码的编写(Python语言)&a…...

STM32CubeIDE(CAN)
目录 一、概念 1、简述 2、CAN 的几种模式 二、实践 1、环回模式轮询通信 1.1 软件配置 1.2 代码编写 2、环回模式中断通信 2.1 软件配置 2.2 代码编写 一、概念 1、简述 STM32微控制器系列包含多个型号,其中一些型号集成了CAN(Controller Are…...

GO Channel使用详解(各种场景下的最佳实践)
GO Channel使用详解(各种场景下的最佳实践) 一个知识点:通过反射的方式执行 select 语句,在处理很多的 case clause,尤其是不定长的 case clause 的时候,非常有用。而且,在后面介绍任务编排的实现时,我也会采用这种方法,所以,我先带你具体学习下 Channel 的反射用法…...

SwiftUI 5.0(iOS 17)滚动视图的滚动目标行为(Target Behavior)解惑和实战
概览 在 SwiftUI 的开发过程中我们常说:“屏幕不够,滚动来凑”。可见滚动视图对于超长内容的呈现有着多么秉轴持钧的重要作用。 这不,从 SwiftUI 5.0(iOS 17)开始苹果又为滚动视图增加了全新的功能。但是官方的示例可…...

picker 构建记录
picker 构建记录 tomlinuxtom:~/openverify/picker$ cd picker bash: cd: picker: 没有那个文件或目录 tomlinuxtom:~/openverify/picker$ export BUILD_XSPCOMM_SWIGpython tomlinuxtom:~/openverify/picker$ make rm -rf temp build /home/tom/Tools/verible-v0.0-3724/bin/…...

Docker部署kafka,Docker所在宿主机以外主机访问
# 安装启动zookeeper docker run -d --name zookeeper --publish 2181:2181 --volume /etc/localtime:/etc/localtime zookeeper:latest --network 指定的网络 -p:设置映射端口(默认2181) -d:后台启动 # 启动kafka docker run -d…...

控制欲过强的Linux小进程
控制欲强?视奸?普通人那才叫视奸,您是皇帝,天下大事无一逃过您的耳目,您想看什么就看什么,臣怀疑他在朋友圈私养兵士,囤积枪甲,蓄意谋反,图谋皇位啊! 哈哈哈哈开个玩笑&…...

探讨元宇宙和VR虚拟现实之间的区别
在数字时代,人们对虚拟现实的兴趣与日俱增。在虚拟现实技术的推动下,出现了两个概念:元宇宙和VR虚拟现实。虽然这两个概念都与虚拟现实有关,但它们有着不同的特点和用途。在本文中,我们将探讨元宇宙和VR虚拟现实之间的…...

Docker Desktop安装
0 Preface/Foreward 1 安装 1.1 运行docker安装包 安装完Docker Desktop后,运行Docker Desktop,出现WSL 2安装不完整情况,具体情况如下: 解决方法:旧版 WSL 的手动安装步骤 | Microsoft Learn 也可以直接下载新的安…...

《Towards Black-Box Membership Inference Attack for Diffusion Models》论文笔记
《Towards Black-Box Membership Inference Attack for Diffusion Models》 Abstract 识别艺术品是否用于训练扩散模型的挑战,重点是人工智能生成的艺术品中的成员推断攻击——copyright protection不需要访问内部模型组件的新型黑盒攻击方法展示了在评估 DALL-E …...

vscode调试nextjs前端后端程序、nextjs api接口
最近有一个项目使用了nextjs框架,并且使用nextjs同时实现了前后端,由于之前前后端都是分离的,前端的调试可以通过在代码种添加debugger或者直接在浏览器中打断点实现,现在想调试后端接口,前面的方式就不适用了。故研究…...

《SeTformer Is What You Need for Vision and Language》
会议:AAAI 年份:2024 论文:DDAE: Towards Deep Dynamic Vision BERT Pretraining - AMinerhttps://www.aminer.cn/pub/6602613613fb2c6cf6c387c2/ddae-towards-deep-dynamic-vision-bert-pretraining 摘要 这篇论文介绍了一种新型的变换器…...

[保姆级教程]uniapp安装使用uViewUI教程
文章目录 创建 UniApp 项目下载uView UI下载安装方式步骤 1: 安装 uView UI步骤 2: 查看uView UI是否下载成功步骤 3: 引入 uView 主 JS 库步骤 4: 引入 uView 的全局 SCSS 主题文件步骤 5: 引入 uView 基础样式步骤 6: 配置 easycom 组件模式注意事项 NPM方式步骤 1: 安装 uVi…...

网络安全法规对企业做等保有哪些具体规定?
网络安全法规对企业做等保的具体规定 根据《中华人民共和国网络安全法》,企业作为网络运营者,需要履行网络安全等级保护制度的相关义务,确保网络安全和数据保护。具体规定包括: 网络安全等级保护制度:企业应根据网络安…...

Java开发中超好用Orika属性映射工具
Orika属性映射工具 引入pom依赖 <dependency><groupId>ma.glasnost.orika</groupId><artifactId>orika-core</artifactId><version>1.5.4</version></dependency>上干货 封装的工具类:OriUtilsimport ma.glasnost.orika.Map…...

qt初入门8:下拉框,输入框模糊查询,提示简单了解 (借助QCompleter)
实现一个简单的模糊查询的逻辑,输入框能提示相关项。 主要借助qt的QCompleter 类( Qt 框架中提供的一个用于自动补全和模糊搜索的类),结合一些控件,比如QComboBox和QLineEdit,实现模糊查询的功能。 1&…...

【qt】VS中如何配置Qt环境
https://download.qt.io/official_releases/vsaddin/ 首先需要下载一下vsaddin,上面的是下载的网站. 下载的时候可能会出现下图的情况 说明你下的vsaddin和您的VS版本不匹配,所以你可以多下几个其他版本的vsAddin,一般都是和你VS版本相匹配的才可以,如Vs2022,那就试试vsaddin2…...

对于相同网段的IP,部分无法ping通问题
现象1:在Linux上执行 ping 192.168.1.232,无法ping通 分析1:使用ifconfig查询,联网使用eth0口,只能上网192.168.10.xx网段,需要增加网段 解决方法:使用ip addr 查询,本身只具备10网…...

Unity发布XR中用于worldbuilding的全新电子书
通过身临其境的虚拟领域开始旅程,在维度之间传送,或将数字奇迹与现实世界融合——虚拟现实(VR)和混合现实(MR)的千万种可能性将邀请创作者把他们的想象力带入生活。 Unity发布的最新版综合指南将帮助有抱负的创作者和经验丰富的开发者深入研究和理解构建…...

Vue3相比于Vue2进行了哪些更新
1、响应式原理 vue2 vue2中采用 defineProperty 来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,结合发布订阅模式实现响应式。 存在的问题: 检测不到对象属性的添加和删除数组API方法无法监听到需要对…...

Unity UGUI 之 Slider
本文仅作学习笔记与交流,不作任何商业用途 本文包括但不限于unity官方手册,唐老狮,麦扣教程知识,引用会标记,如有不足还请斧正 1.Slider是什么 滑块,由三部分组成:背景 填充条 手柄 填充条就是…...

这7款高效爬虫工具软件,非常实用!
在当今数据驱动的时代,自动化爬虫工具和软件成为了许多企业和个人获取数据的重要手段。这里会介绍6款功能强大、操作简便的自动化爬虫工具,用好了可以更高效地进行数据采集。 1. 八爪鱼采集器 八爪鱼是一款功能强大的桌面端爬虫软件,主打可…...

【OJ】二叉树相关OJ题
✨✨欢迎大家来到Celia的博客✨✨ 🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉 所属专栏:OJ题 个人主页:Celias blog~ 目录 编辑 单值二叉树 题目描述 OJ-单值二叉树 解题思路 …...

Blender中保存透明图片
在Blender中保存透明图片,主要是通过在渲染设置中调整背景透明度,并选择合适的文件格式来保存图像。以下是一个详细的步骤指南: 一、设置渲染属性 打开Blender并加载你想要渲染的模型。在右侧的属性编辑器中,找到并点击“渲染属…...

MySQL之索引优化
1、在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引 例如下面的查询不能使用 actor_id 列的索引: #这是错误的 SELECT actor_id FROM sakila.actor WHERE actor_id 1 5; 优化方式:…...

Spring Boot 与 Amazon S3:快速上传与下载文件的完整指南
概要 在将 Spring Boot 更新到 3 系列时,由于 javax 需要被替换为 jakarta,因此原先依赖于 javax 的 spring-cloud-starter-aws1 将无法使用(虽然在我本地环境中仍然可以正常工作)。为了确保兼容性,我将依赖关系更改为…...

细节剖析:HTTP与HTTPS在安全性、性能等方面的不同!
HTTPS是现代互联网通信的重要基石,通过加密通信、身份验证和数据完整性保护,为数十亿用户提供了安全可靠的互联网体验。 小编整理了2GB程序员相关资料,关注微信公众号“程序员Style”回复“程序员”免费领取! 1、介绍 随着 HTT…...

MySQL面试篇章——MySQL索引
文章目录 MySQL 索引索引分类索引创建和删除索引的执行过程explain 查看执行计划explain 结果字段分析 索引的底层实现原理B-树B树哈希索引 聚集和非聚集索引MyISAM(\*.MYD,*.MYI)主键索引辅助索引(二级索引) InnoDB&a…...

WSL 2 Oracle Linux 9.1 安装配置
文章目录 环境使用体验安装 Oracle Linux 9.1修改默认存储路径默认 root 用户登录启用 systemd启用 SSH 连接WSL 无法 ping 通宿主机和域名WSL 使用主机代理(测试通过)WSL 常用命令 环境 OS:Win11 24H2 (OS 内部版本26120.1252) wsl --versio…...