一个驱动支持多个设备时有两种方式
一个cdev对象管理多个设备 每个cdev对象管理一个设备
一套文件
如何区分呢,open函数传入参数来区分,一个struct inode代表一个真实的文件,struct file表示一个打开的文件
static int key_open(struct inode *inode, struct file *filp)
{
}
struct inode {
kdev_t i_dev; /* inode所在的device代码 */
umode_t i_mode; /* inode的权限 */
uid_t i_uid; /* inode拥有者的id */
gid_t i_gid; /* inode所属的群组id */
kdev_t i_rdev; /* 如果inode代表的是device的话,那此字段将记录device的代码 */
struct inode_operations *i_op;
struct file_operations *i_fop;/* former ->i_op->default_file_ops */
struct char_device *i_cdev;
};
一个cdev管理多个设备
//截取的实际工程代码
static int __init int_key_init(void)
{
ret = alloc_chrdev_region(&dev->devid, 0, 2, "key");
/* 添加字符设备 */
dev->c_dev.owner = THIS_MODULE;
cdev_init(&dev->c_dev, &int_key_fops);
ret = cdev_add(&dev->c_dev, dev->devid, 2);
}
static int key_open(struct inode *inode, struct file *filp)
{
//取次设备号来区分设备,将区别存入打开文件的私有数据
switch (MINOR(inode->i_rdev)) {
case 0:
//filp->private_data = xxx;
break;
case 1:
//filp->private_data = xxx;
break;
}
}
//ex,使用私有数据来具体操作哪个按键
static ssize_t key_read(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
struct key_dev* dev = (struct key_dev*)filp->private_data;
key_value = atomic_read(dev->key.value);
(void)copy_to_user(buf, &key_value, sizeof(key_value));
return 0;
}
一个cdev管理一个设备
struct led_dev {
struct cdev c_dev;
xxxxx
}
struct led_dev gpioled[2];
static int __init int_key_init(void)
{
dev_t devid;
ret = alloc_chrdev_region(&devid, 0, 2, "key");
/* 添加字符设备 */
dev->c_dev.owner = THIS_MODULE;
cdev_init(&dev[0]->c_dev, &int_key_fops);
ret = cdev_add(&dev[0]->c_dev, devid, 1);
cdev_init(&dev[1],->c_dev &int_key_fops);
ret = cdev_add(&dev[1]->c_dev, devid + 1, 1)
}
static int key_open(struct inode *inode, struct file *filp)
{
filp->private_data = container_of(ionde->i_cdev ,struct led_dev, c_dev);
}
}