天天看點

字元裝置驅動-使用alloc_chrdev_region+cdev注冊裝置驅動

Lalloc_chrdev_region函數原型如下,它是我們用來向核心申請主裝置号時用的,與register_chrdev_region不同的是,alloc_chrdev_region是讓核心配置設定給我們一個尚未使用的主裝置号,不是由我們自己指定的,該函數的四個傳參意義如下:

dev :alloc_chrdev_region函數向核心申請下來的裝置号

baseminor :次裝置号的起始

count: 申請次裝置号的個數

name :執行 cat /proc/devices顯示的名稱

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,

            const char *name)

{

    struct char_device_struct *cd;

    cd = __register_chrdev_region(0, baseminor, count, name);

    if (IS_ERR(cd))

        return PTR_ERR(cd);

    *dev = MKDEV(cd->major, cd->baseminor);

    return 0;

}

cdev的使用:

1.執行cdev_init函數,将cdev和file_operations關聯起來

2.使用cdev_add函數,将cdev和裝置号關聯起來

void cdev_init(struct cdev *cdev, const struct file_operations *fops)

{

    memset(cdev, 0, sizeof *cdev);

    INIT_LIST_HEAD(&cdev->list);

    kobject_init(&cdev->kobj, &ktype_cdev_default);

    cdev->ops = fops;

}

demo

#include <linux/module.h>       // module_init  module_exit

#include <linux/init.h>         // __init   __exit

#include <linux/cdev.h>

#include <linux/fs.h>

#define MYMAJOR     200

#define MYNAME      "chardev_test_byHc"

//DEVICE ID

dev_t devid;

static int chardev_open(struct inode *inode, struct file *file)

{

    printk(KERN_INFO "chardev open\n");

    return 0;

}

static ssize_t chardev_read(struct file *file, char __user *buf,

          size_t size, loff_t *ppos)

{

    return 0;

}

static const struct file_operations chardev_fops = { 

    .open = chardev_open,

    .read = chardev_read,

};

static struct

{

    struct cdev cdev;

}chardev;

static int __init mymodule_init(void)

{   

    int ret = 0;

    printk(KERN_INFO "chrdev_init helloworld init\n");

    cdev_init(&chardev.cdev,&chardev_fops);

    alloc_chrdev_region(&devid,2,255,MYNAME);

    printk(KERN_INFO "MAJOR Number is %d\n",MAJOR(devid));

    printk(KERN_INFO "MINOR Number is %d\n",MINOR(devid));

    cdev_add(&chardev.cdev,devid,255);

    return 0;

}

static void __exit mymodule_exit(void)

{

    printk(KERN_INFO "chrdev_exit helloworld exit\n");

    cdev_del(&chardev.cdev);

    unregister_chrdev_region(devid,255);

}

module_init(mymodule_init);

module_exit(mymodule_exit);

// MODULE_xxx這種宏作用是用來添加子產品描述資訊

MODULE_LICENSE("GPL");              // 描述子產品的許可證

MODULE_AUTHOR("Hanc");              // 描述子產品的作者

MODULE_DESCRIPTION("module test");  // 描述子產品的介紹資訊

MODULE_ALIAS("alias xxx");          // 描述子產品的别名資訊

--------------------- 

作者:明故宮的記憶 

來源:CSDN 

原文:https://blog.csdn.net/weixin_42314225/article/details/81112217 

版權聲明:本文為部落客原創文章,轉載請附上博文連結!