概述
misc设备驱动是Linux内核中的一种特殊类型的驱动程序,它用于管理那些没有与特定硬件设备相关联的设备。这些设备通常是由用户空间的应用程序创建和控制的,例如设备文件/dev/null和/dev/random。
miscdevice本质上也是字符设备,只是在miscdevice核心层的misc_init()函数中,通过register_chrdev(MISC_MAJOR,”misc”,&misc_fops)注册了字符设备,而具体miscdevice实例调用misc_register()的时候又自动完成了device_create()、获取动态次设备号的动作。
miscdevice的主设备号是固定的,MISC_MAJOR定义为10,在Linux内核中,大概可以找到200多处使用miscdevice框架结构的驱动。
相关头文件、结构体、API
1.头文件:
<linux/miscdevice.h>
:定义了miscdevice结构体和相关的函数原型。
2.结构体:
- struct miscdevice:用于描述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; // 设备节点权限
};
3.API:
- misc_register():用于将misc设备注册到系统中。
函数原型如下:
int misc_register(struct miscdevice *misc);
- misc_deregister():用于将misc设备从系统中注销。
函数原型如下:
void misc_deregister(struct miscdevice *misc);
模板
#include <linux/cdev.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/types.h>
struct xxx_dev_t {
struct miscdevice miscdev;
};
static struct xxx_dev_t xxx_dev;
static int xxx_open(struct inode* inode, struct file* filp)
{
filp->private_data = &xxx_dev;
return 0;
}
static ssize_t xxx_read(struct file* filp, char __user* buf, size_t cnt, loff_t* offt)
{
return 0;
}
static ssize_t xxx_write(struct file* filp, const char __user* buf, size_t cnt, loff_t* offt)
{
return 0;
}
static long xxx_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
return 0;
}
static int xxx_release(struct inode* inode, struct file* filp)
{
return 0;
}
static struct file_operations xxx_fops = {
.owner = THIS_MODULE,
.open = xxx_open,
.read = xxx_read,
.write = xxx_write,
.release = xxx_release,
.unlocked_ioctl = xxx_ioctl,
};
static int __init xxx_init(void)
{
int ret = 0;
xxx_dev.miscdev.minor = MISC_DYNAMIC_MINOR;
xxx_dev.miscdev.name = "xxx";
xxx_dev.miscdev.fops = &xxx_fops;
ret = misc_register(&xxx_dev.miscdev);
return ret;
}
static void __exit xxx_exit(void)
{
misc_deregister(&xxx_dev.miscdev);
}
module_init(xxx_init);
module_exit(xxx_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("author");