单页做网站教程,php网站安装包制作,如何做网站连接,网站如何建数据库i.MX8MM处理器采用了先进的14LPCFinFET工艺#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53#xff0c;单核Cortex-M4#xff0c;多达五个内核 #xff0c;主频高达1.8GHz#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…i.MX8MM处理器采用了先进的14LPCFinFET工艺提供更快的速度和更高的电源效率;四核Cortex-A53单核Cortex-M4多达五个内核 主频高达1.8GHz2G 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.78Qt5.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?p10
程序源码在网盘资料“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_MINORmiscdevice核心层会自动找一个空闲的次设备号否则用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(ret0) //判断杂项设备是否注册成功{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 那么现在最简单的杂项设备已经完成了。