cdev bus and class
谨以此文纪念过往的岁月
一.前言
相信很多刚开始学习驱动的人的都会对cdev platform以及class这三者之间的关系不是很理解。本文记录本人对于此的一点见解,不对之处请指教。
二.三角关系
cdev其实是说明设备的真正所属类型,在linux中分为字符类型,块类型和网络类型,几乎所有的设备都可以分配到这三种类型之中。
bus其实是指设备的总线,说白了就是设备和驱动根据什么样的匹配方式来进行匹配。形象一点就是bus就是一条大道,而所有的driver在一边,而所有的device在大路的另一边,而bus就是将device和driver连接起来,如driver A可以驱动device A和device B,而bus就把driver和device连接起来。其实用这样的比喻并不是很确切,不过这样对于理解bus的功能会形象不少。常见的bus有usb pci i2c platform等等总线。总线只会在设备注册卸载和驱动注册卸载时才会有用。
而class则是一类设备的总和。怎么来说呢,就好像是男人和女人都属于人类一样,device A和device B 都属于class A,则创建设备节点时就可以在传入class参数是用
class A作为参数传入。
三.具体实现
以platform总线为例:
申请和注册和注销一个platform设备
globalmem_devp->dev = platform_device_alloc("globalmem",-1);
platform_device_register(globalmem_devp->dev);
platform_device_unregister(globalmem_devp->dev);
注册和卸载一个platform驱动
platform_driver_register(globalmem_devp->drv);
platform_driver_unregister(globalmem_devp->drv);
不过globalmem_devp->drv->name 应该为"globalmem",这个跟总线的匹配规则有关,platform总线采用name匹配。这里的platform设备和驱动与cdev没有半点关系。无论我的设备类型是cdev还是block的,这里是不管的,你可以把它看成独立的一部分。
以cdev为例:
比如说我想注册一个主设备和多个从设备,都是globalmem以类的,有很多人在刚开始学习例程时,以为platform设备名和我注册的cdev的设备号名是一样的,总以为这两者有什么不可告人的秘密,其实不然,这两个并没有半点关系。
注册设备号以及注册一个cdev设备。
register_chrdev_region(devno, 2, "globalmem");
int err, devno = MKDEV(globalmem_major, index);
cdev_init(&dev->cdev, &globalmem_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &globalmem_fops;
err = cdev_add(&dev->cdev, devno, 2);
创建在/dev下的设备节点:
在这里面就涉及到设备类以及设备节点名。
device_create(globalmem_devp->cls,NULL,devno,NULL,"globalmem%d",index);
这里如何将设备节点与设备操作联系起来的就是通过devno。
创建一个设备类:
globalmem_devp->cls = class_create(THIS_MODULE,"globalT");
到此应该对上面三者关系有了比较清晰的理解,不过在注册这三者时,同时去参考/sys/下的/bus总线,/class 和/devices以及/dev这几个文件夹下面的文件,就会更好的理解了。
阅读(2476) | 评论(0) | 转发(0) |