LINUX字符设备驱动纠正

来源:互联网 发布:小学一年级数学软件 编辑:程序博客网 时间:2024/06/02 06:54

以前的字符设备驱动框架
0、确定主设备号
1、构造file_opeartions
2、register_chrdev(主设备号, name,file_opeartions )
3、入口函数,调用register_chrdev
4、出口函数

缺点:只能有255个字符设备驱动
很多书里面已经建议不用这种方式了

以前的想法:在虚拟文件系统VFS中,调用sys_open,然后以主设备号为下标,在chrdevs里面找到之前注册的file_operation
现在的想法:以主设备号和次设备号来找到file_operation

major = register_chrdev(0, “hello”, &hello_fops);
本来是(主,0)~(主,255),都对应file_opeartions,霸占了255次设备号;

改成:
将其展开:
①:register_chrdev_region/alloc_chrdev_region
region :区域
从(主,次)到(主,次 + n)都对应该file_opeartions结构体
②:cdev_init
③:cdev_add
这样一来理论上可以支持255 * 255个字符设备

其实只不过是将原来的 register_chrdev 拆分成为上面三个点而已;

参考函数:
linux-2.6.22.6\drivers\char\Scx200_gpio.c

static int __init scx200_gpio_init(void){    int rc;    dev_t devid;    if (!scx200_gpio_present()) {        printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n");        return -ENODEV;    }    /* support dev_dbg() with pdev->dev */    pdev = platform_device_alloc(DRVNAME, 0);    if (!pdev)        return -ENOMEM;    rc = platform_device_add(pdev);    if (rc)        goto undo_malloc;    /* nsc_gpio uses dev_dbg(), so needs this */    scx200_gpio_ops.dev = &pdev->dev;    if (major) {        devid = MKDEV(major, 0);        rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio");    } else {        rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio");        major = MAJOR(devid);    }    if (rc < 0) {        dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc);        goto undo_platform_device_add;    }    cdev_init(&scx200_gpio_cdev, &scx200_gpio_fileops);    cdev_add(&scx200_gpio_cdev, devid, MAX_PINS);    return 0; /* succeed */undo_platform_device_add:    platform_device_del(pdev);undo_malloc:    platform_device_put(pdev);    return rc;}
    if (major) {        devid = MKDEV(major, 0);        register_chrdev_region(devid, HELLO_CNT, "hello");  /* (major,0~1) 对应 hello_fops, (major, 2~255)都不对应hello_fops */    } else {        alloc_chrdev_region(&devid, 0, HELLO_CNT, "hello"); /* (major,0~1) 对应 hello_fops, (major, 2~255)都不对应hello_fops */        major = MAJOR(devid);                         }

分析
如果没有主设备号的话,就创建主设备号;
MKDEV(major, 0) 与 register_chrdev_region(devid, 2, “hello”) 表明(major ,0~1) 对应 hello_fops
如果MKDEV(major, 0);中的0改为1的话, register_chrdev_region(devid, 2, “hello”)不变。就是(major ,1~2) 对应 hello_fops

    cdev_init(&hello_cdev, &hello_fops);    cdev_add(&hello_cdev, devid, HELLO_CNT);

分析:创建cdev,和添加cdev;

原创粉丝点击