【Linux驱动层】iTOP-RK3568学习之路(四):杂项设备驱动框架

一、杂项设备驱动简介


在 Linux 中,把无法归类的五花八门的设备定义成杂项设备。相较于字符设备,杂项设备有以下两个优点:

(1)节省主设备号:杂项设备的主设备号固定为 10,而字符设备不管是动态分配还是静态分配设备号,都会消耗一个主设备号,进而造成了主设备号浪费。当系统中注册了多个 misc 设备驱动时,只需使用子设备号进行区分即可

(2)使用简单:当使用普通的字符设备驱动时,如果开发人员需要导出操作接口给用户空间,就需要注册对应的字符驱动,并创建字符设备 class 从而自动在/dev 下生成设备节点,而 misc驱动只需要将基本信息通过结构体传递给相应处理函数即可。


二、总体框架图


在这里插入图片描述


三、杂项设备相关函数


杂项设备miscdevice 结 构 体

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_DYNAMIC_MINOR,表示自动分配子设备号。
  • name 表示 misc 设备的名字。misc 设备驱动注册成功之后,会在 dev 目录下生成名为 name的设备节点。
  • fops 指向了 file_operations 的结构体,表示字符设备的操作集合。

杂项设备的注册

函数原型:
	int misc_register(struct miscdevice *misc);
函数作用:
	基于misc_class构造一个设备,将miscdevice结构挂载到misc_list列表上,
    并初始化与linux设备模型相关的结构。进而起到杂项设备注册的作用。
参数含义:
	misc: 杂项设备的结构体指针
函数返回值:
    申请成功返回 0,申请失败返回负数

杂项设备的卸载

函数原型:
	int misc_deregister(struct miscdevice *misc);
函数作用:
	从 mist_list 中删除 miscdevice,进而起到杂项设备卸载的作用。
参数含义:
	misc: 杂项设备的结构体指针
函数返回值:
    卸载成功返回 0,申请失败返回负数

四、实例代码


#include <linux/module.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>


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


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


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


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


struct file_operations cdev_test_ops={
    .owner = THIS_MODULE,    // 文件操作结构体
    .open = cdev_test_open,
    .read = cdev_test_read,
    .write = cdev_test_write,
    .release = cdev_test_release,
};


struct miscdevice misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "test",
    .fops = &cdev_test_ops
};


static int chardev_init(void){
    int ret;     //返回值判断

    ret = misc_register(&misc_dev);     //注册杂项设备
    if (ret < 0)
    {
        printk("misc_register failed\r\n");
    }
    printk("misc_register ok\r\n");

    return 0;
}


static void chardev_exit(void){
    misc_deregister(&misc_dev);  //卸载杂项设备
    printk("chardev_exit!\n");
}


module_init(chardev_init);
module_exit(chardev_exit);


MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("ZSY");
MODULE_VERSION("V1.0");



  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值