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

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

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

#if 0
major = register_chrdev(0, "hello", &hello_fops); /* (major,  0), (major, 1), ..., (major, 255)都对应hello_fops */
#else
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);                     
}

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值