一. 简介
每个硬件设备都有一些属性,例如,主设备号
(dev_t)
,类
(class)
、设备
(device)
、开关状态
(state)
等等,在比较规范的驱动编写时,是将这些属性写成一个结构体类型,编写驱动
open()
函数的时候,将设备结构体作为私有数据添加到设备文件中。
二. 新字符设备驱动中文件的私有数据
每个硬件设备都有一些属性,例如,主设备号
(dev_t)
,类
(class)
、设备
(device)
、开关状态
(state)
等等,在编写驱动的时候,你可以将这些属性全部写成变量的形式,如下所示:
dev_t devid; /* 设备号 */
struct cdev cdev; /* cdev */
struct class *class; /* 类 */
struct device *device; /* 设备 */
int major; /* 主设备号 */
int minor; /* 次设备号 */
这样写肯定没有问题,但是这样写不专业!
对于一个设备的所有属性信息我们最好将其做成一个结构体。编写驱动 open() 函数的时候将设备结构体作为私有数据添加到设备文件中。
注意:file 结构体中(open(),write(),read()等函数的入参)有一个成员变量是指针,是私有数据指针 private_data。
open() 函数中,将设备结构体作为私有数据添加到设备文件中:
/* 设备结构体 */
struct test_dev{
dev_t devid; /* 设备号 */
struct cdev cdev; /* cdev */
struct class *class; /* 类 */
struct device *device; /* 设备 */
int major; /* 主设备号 */
int minor; /* 次设备号 */
};
struct test_dev testdev;
/* open 函数 */
static int test_open(struct inode *inode, struct file *filp)
{
filp->private_data = &testdev; /* 设置私有数据 */
return 0;
}
在
open()
函数里面设置好私有数据以后,在
write()
、
read
()、
close()
等函数中直接读取 私有数据指针
private_data 即可得到设备结构体。
例如,write()函数中,可以实现如下转换:
static ssize_t newchrled_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
{
int ret = 0;
struct newchrled_dev* dev = (struct newchrled_dev*)file->private_data;
.......................
return 0;
}
同理,release()函数(即close()函数),同样的转换:
int newchrled_release(struct inode * inode, struct file * file)
{
struct newchrled_dev *dev = (struct newchrled_dev*)file->private_data;
printk("led_release\r\n");
return 0;
}
在Linux内核源码的驱动代码中,这种用法很普遍。
这就是私用数据的使用方法。