创建字符设备与生成设备节点

来源:互联网 发布:onenote for mac 离线 编辑:程序博客网 时间:2024/04/19 06:17
使用udev在/dev/下动态生成设备文件

create_chrdev.c
---------------------------------------------
#include <linux/types.h>     //dev_t 
#include <linux/cdev.h>      //struct cdev 
#include <linux/fs.h>        //alloc_chrdev_region()
#include <linux/device.h>    //class_create()

dev_t                  devid;
static struct cdev     *led_cdev; 
static int             led_Major = 0;
static int             led_Minor = 0;
static struct class    *led_class;

static struct file_operations led_fops = { 
    .owner        = THIS_MODULE, 
};

static int __init hello_init(void)
{
    int err;

    //初始化cdev 
    led_cdev        = cdev_alloc(); 
    cdev_init(led_cdev, &led_fops); 
    led_cdev->owner = THIS_MODULE;

    //动态获取主设备号(dev_t devid中包含"主设备号"和"次设备号"信息) 
    alloc_chrdev_region(&devid, 66, 1, "led"); 
    led_Major = MAJOR(devid);
    led_Minor = MINOR(devid);
    printk(KERN_INFO "I was assigned major number %d.\n", led_Major); 
    printk(KERN_INFO "I was assigned minor number %d.\n", led_Minor);

    //注册字符设备 (1)
    err = cdev_add(led_cdev, devid, 1); 
    if (err) { 
        printk(KERN_NOTICE "Error %d adding device\n", err); 
        return -1; 
    }

    led_class = class_create(THIS_MODULE, "led_class1"); 
    if (IS_ERR(led_class)) { 
        printk(KERN_INFO "create class error\n"); 
        return -1; 
    } 
    class_device_create(led_class, NULL, devid, NULL, "led" "%d", MINOR(devid));    


    return 0;
}

static void __exit hello_exit(void)
{
    unregister_chrdev_region(devid, 1); 
    cdev_del(led_cdev);

    class_device_destroy(led_class, devid); 
    class_destroy(led_class);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zengxiaolong ");
MODULE_DESCRIPTION("A sample driver");
MODULE_SUPPORTED_DEVICE("testdevice");


(1)cdev_add()执行后将会在/proc/devices文件中看到"252 led",但是在/dev/目录下没有生成相应的设备文件。直到class_device_create()执行后才会在/dev/目录下生成设备文件led66。而class_create()执行后会在/sys/class/目录下生成led_class1目录

Makefile
---------------------------------------------
all: default
obj-m += create_chrdev.o

default:
    make -C /home/zxl/soft/kernel/linux-2.6.22 M=`pwd` modules
clean:

    make -C /home/zxl/soft/kernel/linux-2.6.22 M=`pwd` clean

 

 

 

 

字符设备的生成 -- 这个版本简洁
-------------------------------------------------------
static struct class    *node_class;

static int __init init_mtdchar(void)
{
    if (register_chrdev(CHAR_MAJOR, "dev_node", &node_fops)) 
    {
        printk(KERN_NOTICE "Can't allocate major number %d.\n", CHAR_MAJOR);
        return -EAGAIN;
    }

    node_class = class_create(THIS_MODULE, "dev_node_class");

    if (IS_ERR(node_class)) {
        printk(KERN_ERR "Error creating node_class.\n");
        unregister_chrdev(CHAR_MAJOR, "dev_node");
        return PTR_ERR(node_class);
    }

    class_device_create(node_class, NULL, MKDEV(CHAR_MAJOR, 0), NULL, 
            "node_name" "%d", CHAR_MINOR); 

    return 0;
}

static void __exit cleanup_mtdchar(void)
{
    class_device_destroy(node_class, MKDEV(CHAR_MAJOR, 0));
    class_destroy(node_class);
    unregister_chrdev(CHAR_MAJOR, "dev_node");
}

 

 

 

linux-2.6.21.7 内核中的使用实例
-------------------------------------------------------
static void adbdev_init(void)
{
    if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
        printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR);
        return;
    }

    adb_dev_class = class_create(THIS_MODULE, "adb");
    if (IS_ERR(adb_dev_class))
        return;
    class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
}

 

 

 

 

linux-2.6.28 内核中的使用实例
-------------------------------------------------------
static void __init adbdev_init(void)
{
    if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
        printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR);
        return;
    }

    adb_dev_class = class_create(THIS_MODULE, "adb");
    if (IS_ERR(adb_dev_class))
        return;
    device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");

    platform_device_register(&adb_pfdev);
    platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
}

原创粉丝点击