编写linux驱动程序时,通常在驱动开发中会为设备定义相关的设备结构体,将硬件属性的描述信息全部放在该结构体中
Linux 中并没有明确规定要使用文件私有数据,但是在 linux 驱动源码中,广泛使用了文件私有数据,这是 Linux 驱动遵循的“潜规则”,实际上也体现了Linux 面向对象的思想。structfile 结构体中专门为用户留了一个域用于定义私有数据。结构体内容如下所示:
struct file {
union {
struct llist_node fu_llist;
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
/*
* Protects f_ep_links, f_flags.
* Must not be taken from IRQ context.
*/
spinlock_t f_lock;
enum rw_hint f_write_hint;
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
struct mutex f_pos_lock;
loff_t f_pos;
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* needed for tty driver, and maybe others */
void *private_data;
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head f_ep_links;
struct list_head f_tfile_llink;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
errseq_t f_wb_err;
}
文件私有数据的概念在 Linux 驱动中有着非常广泛的应用,文件私有数据就是将私有数据private_data 指向设备结构体。通过它可以将私有数据一路从open 函数带到read, write函数层层传入。一般是在 open 的时候赋值,read、write 时使用。open 函数中私有数据的使用如下所示
struct device_test dev1;
static int cdev_test_open(struct inode *inode,struct file *file)
{
file->private_data=&dev1;
return 0;
};
在上述代码中,定义了一个设备结构体 dev1,然后在 open 函数中,将私有数据private_data指向了设备结构体 dev1。我们可以在 read write 函数中通过 private_data 访问设备结构体,如下所示:
static ssize_t cdev_test_write(struct file *file,const char _user *buf, size_t size,loff_t *off_t)
{
struct device_test *test_dev=(struct device_test *)file->private_data;
return 0;
}