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; 
}


  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值