Linux内核的misc框架

本文详细介绍了Linux内核的misc框架,它用于管理那些不易分类的设备,如ADC和WATCHDOG。文章解析了misc驱动框架的初始化、设备注册过程,以及如何编写和注册misc驱动。通过misc_register函数,开发者可以方便地创建和管理设备,而无需关心主设备号和次设备号的分配。此外,文章还展示了如何编写一个简单的misc设备驱动程序。
摘要由CSDN通过智能技术生成

Linux内核为每种设备都抽象出了框架,开发人员只需往框架中填充信息即可进行设备的注册。下面来讲解一下Linux内核的misc框架。
misc又叫杂散类设备,在早期的内核中,向ADC、WATCHDOG、PWM等设备都没有一个明确的框架,于是这些设备就都归类到了misc框架。在后来内核版本中才逐步完善各种设备框架。下面就来简单了解一下misc设备的框架,以及使用misc框架来写一个测试驱动。

    misc框架代码

static int __init misc_init(void)
{
    int err;

#ifdef CONFIG_PROC_FS
    proc_create("misc", 0, NULL, &misc_proc_fops);
#endif
    misc_class = class_create(THIS_MODULE, "misc");  // 创建类,类名叫misc
    err = PTR_ERR(misc_class);
    if (IS_ERR(misc_class))
        goto fail_remove;

    err = -EIO;
    if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))  // 注册misc字符设备,设备号是10
        goto fail_printk;
    misc_class->devnode = misc_devnode;
    return 0;

fail_printk:
    printk("unable to get major %d for misc devices\n", MISC_MAJOR);
    class_destroy(misc_class);
fail_remove:
    remove_proc_entry("misc", NULL);
    return err;
}

  

misc_init函数是初始化misc框架,首先会先创建一个叫misc的类,然后在这个类中注册一个叫misc的设备,设备号是10。


可以看到在内核中,通过命令可以查看misc设备的主设备号是10,在class中有一个叫misc的类。

 

 

int misc_register(struct miscdevice * misc)
{
    dev_t dev;
    int err = 0;

    INIT_LIST_HEAD(&misc->list);

    mutex_lock(&misc_mtx);

    if (misc->minor == MISC_DYNAMIC_MINOR) { // 判断次设备是否为255,如果是就自动分配次设备号,否则就使用开发人员传进来的次设备号
        int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
        if (i >= DYNAMIC_MINORS) {
            err = -EBUSY;
            goto out;
        }
        misc->minor = DYNAMIC_MINORS - i - 1;
        set_bit(i, misc_minors);
    } else {
        struct miscdevice *c;

        list_for_each_entry(c, &misc_list, list) {
            if (c->minor == misc->minor) {
                err = -EBUSY;
                goto out;
            }
        }
    }

    dev = MKDEV(MISC_MAJOR, misc->minor); // 将主设备号和次设备号进行合并得到设备号

    misc->this_device =
        device_create_with_groups(misc_class, misc->parent, dev,
                      misc, misc->groups, "%s", misc->name); // 创建设备
    if (IS_ERR(misc->this_device)) {
        int i = DYNAMIC_MINORS - misc->minor - 1;
        if (i < DYNAMIC_MINORS && i >= 0)
            clear_bit(i, misc_minors);
        err = PTR_ERR(misc->this_device);
        goto out;
    }

    /*
     * Add it to the front, so that later devices can "override"
     * earlier defaults
     */
    list_add(&misc->list, &misc_list);
 out:
    mutex_unlock(&misc_mtx);
    return err;
}

 
 

misc_register是内核提供给开发人员的注册misc设备的接口函数。该函数主要做了两件事情,首先判断次设备号是否需要自动分配,然后调用device_create_with_groups注册设备。

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

   

struct miscdevice结构体需要开发者对里面的成员变量进行填充,填充完之后调用misc_register注册设备。

下面来写一个简单的misc设备驱动。
驱动程序

struct miscdevice led_misc;  // 定义misc结构体变量

ssize_t chrdev_read (struct file *file, char __user *usr, size_t size, loff_t *loff)
{
    printk("%s\r\n",__func__);
    return 0;
}
int chrdev_open (struct inode *inode, struct file *file)
{
    printk("%s\r\n",__func__);
    return 0;
}
int chrdev_release (struct inode *inode, struct file *file)
{
    printk("%s\r\n",__func__);
    return 0;
}
struct file_operations led_fops =
{
    .open    = chrdev_open,
    .read    = chrdev_read,
    .release = chrdev_release,
};


static int __init chrdev_init(void)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值