LINUX字符设备驱动纠正

以前的字符设备驱动框架
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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值