驱动-杂项设备

我们已经对字符设备驱动框架有了一定的理解, 而本章要讲解的杂
项设备属于特殊的一种字符型设备, 是对字符设备的一种封装, 为最简单的字符设备。


基本概念

杂项设备驱动具有以下特点:

  • 主设备号固定为10
  • 次设备号动态分配
  • 简化了字符设备驱动的注册流程
  • 适用于功能简单的设备

参考资料

字符设备相关资料,建议对比看看。尤其是这里的杂项设备和标准字符设备对比看,看流程、方法 对比来理解。
字符设备号申请
字符设备注册
创建字符设备节点

主要数据结构 miscdevice

在 驱 动 中 使 用 miscdevice 结 构 体 描 述 misc 设 备 , 该 结 构 体 定 义 在 “ 内 核 源 码
/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 指次设备号, 可以从“内核源码/include/linux/miscdevice.h”文件中预定义的次设备号
挑选, 也可以自行定义子设备号

  • minor:通常情况下将该参数设置为MISC_DYNAMIC_MINOR, 表示自动分配子设备号
  • name 表示 misc 设备的名字。 misc 设备驱动注册成功之后, 会在 dev 目录下生成名为 name
    的设备节点。
  • fops 指向了 file_operations 的结构体, 表示字符设备的操作集合。

杂项设备的注册和卸载

不同于字符设备的注册和卸载的繁琐, 杂项设备的注册可以直接使用函数 misc_register 函
数来完成, 杂项设备的卸载可以直接使用 misc_deregister 函数来完成。

注册 misc_register(struct miscdevice *misc)

基于 misc_class 构造一个设备, 将 miscdevice 结构挂载到 misc_list 列表上, 并初始化与 linux
设备模型相关的结构。 进而起到杂项设备注册的作用

卸载 misc_deregister

从 mist_list 中删除 miscdevice, 进而起到杂项设备卸载的作用

实验

测试-源码demo


#include <linux/init.h>     //初始化的头文件
#include <linux/module.h>   //最基本的文件,支持动态添加和卸载模块
#include <linux/fs.h>       //注册设备节点的文件结构体
#include <linux/miscdevice.h>        //注册杂项设备头文件


static int chrdev_open(struct inode *inode, struct file *file)
{
    printk("This is chrdev_open \n");
    return 0;
}

static ssize_t chrdev_read(struct file *file,char __user *buf, size_t size, loff_t *off)
{
    printk("This is chrdev_read \n");
    return 0;
}

static ssize_t chrdev_write(struct file *file,const char __user *buf,size_t size,loff_t *off)
{
    printk("This is chrdev_write \n");
    return 0;
}
static int chrdev_release(struct inode *inode, struct file *file)
{
    return 0;
}

static struct file_operations misc_fops = {
	.owner=THIS_MODULE,//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块
    .open = chrdev_open,//将open字段指向chrdev_open(...)函数
    .read = chrdev_read,//将open字段指向chrdev_read(...)函数
    .write = chrdev_write,//将open字段指向chrdev_write(...)函数
    .release = chrdev_release,//将open字段指向chrdev_release(...)函数
};//定义file_operations结构体类型的变量misc_fops

 struct miscdevice misc_dev = {       //杂项设备结构体
    .minor = MISC_DYNAMIC_MINOR,     //动态申请的次设备号
    .name = "hello_misc",                  //杂项设备名字是hello_misc
    .fops = &misc_fops,              //文件操作集
};
 

static int __init misc_init(void)//驱动入口函数
{
    int ret;//定义int类型的变量ret,用来判断函数返回值
     
    ret = misc_register(&misc_dev); //在初始化函数中注册杂项设备
 
    if(ret < 0 ){
        printk("cdev_add is error\n");
    }
   
    printk("misc registe is succeed \n");//打印注册杂项设备成功


    return 0;
}
static void __exit misc_exit(void)//驱动出口函数
{
     misc_deregister(&misc_dev);     //在卸载函数中注销杂项设备
    printk(" misc goodbye! \n");
    printk("module  exit \n");

}

module_init(misc_init);//注册入口函数
module_exit(misc_exit);//注册出口函数
MODULE_LICENSE("GPL v2");//同意GPL开源协议
MODULE_AUTHOR("wang fang chen "); //作者信息

源码分析:misc_dev 、file_operations、misc_register

  • misc_dev:杂项设备结构体。 标准字符设备的字符设备结构体为 cdev; 对于设备号申请,申请设备号的结构体是 dev_t
  • file_operations: 文件操作结构体,这里和标准字符设备结构体一样的。
  • misc_register:杂项设备的注册就一个函数方法;标准字符设备的注册就需要:初始化结构体、添加字符设备到内核;同时还需要创建类、创建类下面的设备

编译文件 Makefile

#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += miscdevice.o
KDIR :=/home/wfc123/Linux/rk356x_linux/kernel
PWD ?= $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean

测试

insmod miscdevice.ko

在这里插入图片描述
misc registe is succeed” ,说明 misc 驱动注册成功。 输入以下命令查看加载的驱动模块,

在这里插入图片描述

找class 下的对应的杂项 device ls /sys/class/misc

到/sys/class/misc 目录下, 可以看到名为“test” 的文件夹已经被创建了, 在/sys/clas
s/misc 目录下有 misc 类的所有设备, 每个注册的杂项设备对应一个文件夹目录, 如下图

在这里插入图片描述

查看dev 下生成的杂项设备 ls /dev/hello_misc

[root@topeet:/]# ls /dev/hello_misc
/dev/hello_misc

如果需要查看所有信息,后面加上参数 -al ,结果如下:

[root@topeet:/]# ls /dev/hello_misc  -al
crw------- 1 root root 10, 53 Jan  1 14:51 /dev/hello_misc
[root@topeet:/]#

可以看到这个杂项设备 主设备号10 次设备号53

总结

看杂项设备还是要和标准字符设备对比来看,

  • 主设备号固定为10,次设备号动态分配,简化了字符设备驱动的注册流程,适用于功能简单的设备
  • 杂项设备也有自己的结构体miscdevice 、file_operations ,却别与标准字符设备的 设备号结构体dev_t ,注册的字符设备结构体cdev ,文件操作集合结构体file_operations
  • 操作流程上:杂项设备开发流程是 将杂项设备结构体miscdevice通过file_operations 结构体关联起来,然后通过方法 misc_register(&misc_dev) 注册一次 就完成了整个开发流程。 但是标准字符设备开发流程是 申请设备号->初始化字符设备->添加字符设备到内核-> /sys/class 下面的字符类创建->创建类下面的设备创建
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值