在Linux的struct file
结构体中,专门为用户留了一个域用于定义私有数据。这意味着,在编写Linux驱动时,开发者可以在这个域中存储与文件相关的私有数据,这些数据对于驱动来说是私有的,不会被其他部分(如内核的其他部分或用户空间的程序)直接访问。
尽管Linux本身并没有明确规定要使用文件私有数据。这实际上是Linux驱动遵循的一种“潜规则”,体现了Linux面向对象的思想
使用私有数据兼容不同的设备:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/modulepram.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/asm-generic/uaccess.h>
struct device_test={
dev_t dev_num;
int major;
int minor;
struct cdev cdev_test;
struct class *class;
struct device *device;
char kbuf[32];
}
struct device_test dev1;
static int cdev_test_open(struct inode *node, struct file *file)
{
file->private_data=&dev1;
printk("cdev_test_open \n");
return 0;
}
static int cdev_test_release(struct inode *node, struct file *file)
{
printk("cdev_test_release \n");
return 0;
}
static ssize_t cdev_test_read (struct file *file, char __user *buf, size_t size, loff_t *off)
{
struct device_test *test_dev=(struct device_test *) file->private_data;
char kbuf[64]="123456hello";
copy_to_user(buf,test_dev ->kbuf,strlen(test_dev ->kbuf));
printk("cdev_test_read \n");
}
static ssize_t cdev_test_write (struct file *file, const char __user *buf, size_t size, loff_t *off)
{
struct device_test *test_dev=(struct device_test *) file->private_data;
char kbuf[64];
copy_from_user(test_dev -> kbuf,buf,size);
printk("write buf[%s]\n",test_dev ->kbuf);
printk("cdev_test_write\n");
}
struct file_operations cdev_test_ops={
.owner=THIS_MODULE,
.open=cdev_test_open,
.release=cdev_test_release,
.read=cdev_test_read,
.write=cdev_test_write,
.ioctl=cdev_test_ioctl
};
static int cdv_init(void)
{
int ret;
//动态申请
ret=alloc_chrdev_region(&dev1.dev_num,0,1,"chrdev_num");
if(0 != ret)
{
printk("alloc_chrdev_regionerr %d\n",ret);
return ret;
}
printk("dev_num=%d \n",dev1.dev_num);
dev1.major = MAJOR(dev1.dev_num);
dev1.minor = MINOR(dev1.dev_num);
printk("input major=%d minor=%d \n",dev1.major,dev1.minor);
cdev_test.owner= THIS_MODULE;
cdev_init(&dev1.cdev_test,&cdev_test_ops);
cdev_add(&dev1.cdev_test,dev1.dev_num,1);
dev1.class = class_create(THIS_MODULE,"test");
dev1.device = device_create(dev1.class,NULL,dev1.dev_num,NULL,"/dev/test");
printk("cdv init\n");
return 0;
}
static void cdv_exit(void)
{
device_destroy(dev1.class,dev1.dev_num);
classs_destroy(dev1.class);
cdev_del(&dev1.cdev_test);
//释放设备号
unregister_chrdev_region(dev1.dev_num,1);
printk("cdv exit\n");
return 0;
}
module_init(cdv_init);
module_exit(cdv_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SONG");
MODULE_VERSION("v1.0");