字符设备程序---基础篇

来源:互联网 发布:为什么4g网络特别慢 编辑:程序博客网 时间:2024/04/29 21:42

每个字符设备通过<主设备号> <次设备号>来标识,操作一个device就是通过主,次设备号对应到driver中的operation的

一个字符设备可以对应多个次设备号,比如(major,x)~(major,x+n)都对应同一个设备,即同一套file_operations

#if 0major = register_chrdev(0, "hello", &hello_fops); /* (major,  0), (major, 1), ..., (major, 255)都对应hello_fops */#elseif (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);                     }cdev_init(&hello_cdev, &hello_fops);cdev_add(&hello_cdev, devid, HELLO_CNT);#endif



【手动创建设备结点】

操作一个设备结点,就是通过主,次设备号跟driver匹配起来,从而操作到相应的驱动中的操作函数(file_operation)

cat /proc/devices来查看现在支持的所有设备,包含主设备号,次设备号,名字

mknod /dev/xxx c <主设备号> <次设备号> 来创建设备结点,这个设备结点对应于某个特定的设备

我们可以看出,一个字符设备驱动可以对应多个设备结点(一个字符设备可以对应多个次设备号)


【自动创建设备结点】

1)创建类(可动态创建也可以静态创建)

2)基于这个类创建设备(可动态创建也可以静态创建)

3) udev根据/sys/class/下的设备在/dev/下动态创建设备结点(前提是dev.devt有赋值,例如vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);)

4) /sys/class/下的目录是根据class.name来确定的,例如,对与video来说就是/sys/class/video4linux/videoX

i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");<span></span>//动态创建

i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,     MKDEV(I2C_MAJOR, adap->nr), NULL,     "i2c-%d", adap->nr);if (IS_ERR(i2c_dev->dev)) {res = PTR_ERR(i2c_dev->dev);goto error;}res = device_create_file(i2c_dev->dev, &dev_attr_name);


static struct class video_class = {//静态创建  .name = VIDEO_NAME,  .dev_attrs = video_device_attrs,};/* Part 4: register the device with sysfs */  vdev->dev.class = &video_class;  vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);  if (vdev->parent)    vdev->dev.parent = vdev->parent;  dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);  ret = device_register(&vdev->dev);



cls = class_create(THIS_MODULE, "hello"); //在sys目录下创建hello类class_device_create(cls, NULL, MKDEV(major, 0), NULL, "hello0");//在hello类上创建hello0设备,mdev会自动创建/dev/hello0结点与之对应class_device_create(cls, NULL, MKDEV(major, 1), NULL, "hello1"); * /dev/hello1 */class_device_create(cls, NULL, MKDEV(major, 2), NULL, "hello2"); /* /dev/hello2 */


static struct class video_class = {//静态创建
.name = VIDEO_NAME,
.dev_attrs = video_device_attrs,
};
0 0