1,struct inode 里面的pravitae_data实现数据之间的传递,open到其他函数之间的传递
在open里面里面定义数据,在其他的write,read,ioctl里面访问数据:
open里面打开struct file*filp并且赋值,在read和write里面可以得到struct file*filp的数据,看起来应该对文件的操作。
/******************************************************
为什么引入 pravita_data
在多个用户要使用设备节点时,我们就引入了praviate_data
在open里面定义,在其他的read/write/..里面使用
*******************************************************/
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
#define CHARDEVICIVEDRIVER_MAJOR 0
#define CHARDEVICIVEDRIVER_MINOR 0
#define CHARDEVICIVEDRIVER_COUNT 1
#define CHARDEVICIVEDRIVER_NAME "chardevicedriver"
#define CHARDEVICIVEDRIVER_CLASS_NAME "chardevicedriver_class"
static u32 chardevicedriver_major = CHARDEVICIVEDRIVER_MAJOR;
static u32 chardevicedriver_minor = CHARDEVICIVEDRIVER_MINOR;
struct chardevicedriver_cdev
{
struct device* dev_device;//设备号
struct cdev cdev;
u8 led;
};
static struct chardevicedriver_cdev* chardevicedriver_cdevp = NULL;
static struct class* dev_class = NULL;//设备文件
static struct device* dev_device = NULL;//设备文件
static int chardevicedriver_open(struct inode* inode,struct file* filp)
{
struct chardevicedriver_cdev* pcdev = NULL;
pcdev = container_of(inode->i_cdev,struct chardevicedriver_cdev,cdev);
pcdev->led = MINOR(inode->i_rdev) + 1;
filp->private_data = pcdev; //可供其他函数使用
printk("FILE = %s,FUNCTION = %s,LINE = %d\n",__FILE__,__FUNCTION__,__LINE__);
return 0;
}
ssize_t chardevicedriver_read(struct file* filp,char __user* buf,size_t count,loff_t* f_pos)
{
struct chardevicedriver_cdev* pcdev = filp->private_data;
printk("FILE = %s,FUNCTION = %s,LINE = %d\n",__FILE__,__FUNCTION__,__LINE__);
printk("__FUNCTION__ = %s,:led = %d\n",__FUNCTION__ ,pcdev->led);
return 0;
}
ssize_t chardevicedriver_write(struct file* filp,const char __user* buf,size_t count,loff_t* f_pos)
{
struct chardevicedriver_cdev* pcdev = filp->private_data;
printk("__FUNCTION__ = %s,:led = %d\n",__FUNCTION__ ,pcdev->led);
printk("FILE = %s,FUNCTION = %s,LINE = %d\n",__FILE__,__FUNCTION__,__LINE__);
return 0;
}
long unlocked_chardevicedriver_ioctl(struct file* filp,unsigned int cmd,unsigned long argc)
{
struct chardevicedriver_cdev* pcdev = filp->private_data;
printk("__FUNCTION__ = %s,:led = %d\n",__FUNCTION__ ,pcdev->led);
printk("FILE = %s,FUNCTION = %s,LINE = %d\n",__FILE__,__FUNCTION__,__LINE__);
return 0;
}
static int chardevicedriver_release(struct inode* inode,struct file* filp)
{
struct chardevicedriver_cdev* pcdev = filp->private_data;
printk("__FUNCTION__ = %s,:led = %d\n",__FUNCTION__ ,pcdev->led);
printk("FILE = %s,FUNCTION = %s,LINE = %d\n",__FILE__,__FUNCTION__,__LINE__);
return 0;
}
static struct file_operations chardevicedriver_fops = {
.owner = THIS_MODULE,
.open = chardevicedriver_open,
.write = chardevicedriver_write,
.read = chardevicedriver_read,
//.ioctl = chardevicedriver_ioctl,
.unlocked_ioctl = unlocked_chardevicedriver_ioctl,
.release = chardevicedriver_release,
};
//添加cdev并且创建一个设备文件
static int chardevicedriver_cdev_add(struct chardevicedriver_cdev* pcdev,int index)
{
int ret = -1;
dev_t dev = 0;
printk("chardevicedriver+cdev_add enter success\n");
dev = MKDEV(chardevicedriver_major,chardevicedriver_minor+index);
cdev_init(&(pcdev->cdev),&chardevicedriver_fops);
ret = cdev_add(&(pcdev->cdev),dev,CHARDEVICIVEDRIVER_COUNT);
if(ret <0)
{
printk("cdev_add add dev to cdev failure\n");
return ret;
}
printk("__FUNCTION = %s,dev add to c_dev success\n ",__FUNCTION__);
//create device
pcdev->dev_device = device_create(dev_class,NULL,dev,NULL,"chardevicedriver%d",MINOR(dev));
if(IS_ERR(pcdev->dev_device))
{
printk("chardevicedriver:device_create failure\n");
ret = PTR_ERR(pcdev->dev_device);
return ret;
}
printk("chardevicedriver:class_device_craete success:/dev/chardevicedriver%d\n",MINOR(dev));
return 0;
}
//static struct cdev chardevicedriver_cdev;
static int __init chardevicedriver_init(void)
{
int ret = -1;
dev_t dev = 0; //设备号
printk("function = %s,line = %d\n",__FUNCTION__,__LINE__);
if(chardevicedriver_major)
{
dev = MKDEV(CHARDEVICIVEDRIVER_MAJOR,CHARDEVICIVEDRIVER_MINOR);
ret = register_chrdev_region(dev,CHARDEVICIVEDRIVER_COUNT,CHARDEVICIVEDRIVER_NAME);
if(ret >0)
{
printk("register_chrdev_regin can't getr char device : major = %d,name = %s\n",\
CHARDEVICIVEDRIVER_MAJOR,CHARDEVICIVEDRIVER_NAME);
goto failure_register_chrdev;
}
}
else
{
alloc_chrdev_region(&dev,chardevicedriver_minor,CHARDEVICIVEDRIVER_COUNT,CHARDEVICIVEDRIVER_NAME);
chardevicedriver_major = MAJOR(dev);
printk("chardevicedriver:chardevicedriver_major = %d,chardevicedriver_minor = %d\n",chardevicedriver_major,chardevicedriver_minor);
}
printk("register_chrdev_regin : major = %d,name = %s\n",\
CHARDEVICIVEDRIVER_MAJOR,CHARDEVICIVEDRIVER_NAME);
//注册cdev
chardevicedriver_cdevp = kmalloc(sizeof(struct chardevicedriver_cdev)*CHARDEVICIVEDRIVER_COUNT,GFP_KERNEL);
if(IS_ERR(chardevicedriver_cdevp))
{
printk("chardevicedriver_cdevp:kmalloc space failure\n");
ret = PTR_ERR(chardevicedriver_cdevp);
goto failure_alloc_cdev;
}
memset(chardevicedriver_cdevp,0,sizeof(struct chardevicedriver_cdev)*(CHARDEVICIVEDRIVER_COUNT));
//create device for create device file
dev_class = class_create(THIS_MODULE,CHARDEVICIVEDRIVER_CLASS_NAME);
if(IS_ERR(dev_class))
{
printk("__FUNCTION__:%s,device create failure\n",__FUNCTION__);
ret = PTR_ERR(dev_device);
goto failure_device_create;
}
printk("__FUNCTION__: device_create success:deice_name = %s\n",CHARDEVICIVEDRIVER_CLASS_NAME);
ret = chardevicedriver_cdev_add(chardevicedriver_cdevp,0);
if(ret<0)
{
printk("chardevicedriver_cdev_add return failure\n");
goto failure_add_cdev;
}
printk("chardevicedriver_cdev_add call success:\n");
return ret;
failure_add_cdev:
class_destroy(dev_class);
failure_device_create:
kfree(chardevicedriver_cdevp);
failure_alloc_cdev:
unregister_chrdev_region(dev,CHARDEVICIVEDRIVER_COUNT);
failure_register_chrdev:
return ret;
}
static void __exit chardevicedriver_exit(void)
{
printk("function = %s,line = %d\n",__FUNCTION__,__LINE__);
//delete cdev
cdev_del(&(chardevicedriver_cdevp->cdev));
//destroy device class
class_destroy(dev_class);
kfree(chardevicedriver_cdevp);
chardevicedriver_cdevp = NULL;
unregister_chrdev_region(MKDEV(CHARDEVICIVEDRIVER_MAJOR,CHARDEVICIVEDRIVER_MINOR),CHARDEVICIVEDRIVER_COUNT);
}
module_init(chardevicedriver_init);
module_exit(chardevicedriver_exit);
MODULE_AUTHOR("tangtang");
MODULE_VERSION("0.0.1");
测试程序如下:
#include
#include
#include
#include
#include
int fd;
char ch;
char buf[10];
int main(int argc,char* argv[])
{
fd = open("/dev/chardevicedriver0",O_RDWR);
if(fd < 0)
{
printf(" open char device driver failure\n");
fd = open("/dev/chardevicedriver",O_RDWR);
if(fd < 0)
{
printf(" open char device driver failure\n");
}
}
printf("open char device driver /dev/chardevicedriver1 success\n");
while(1)
{
printf("char device driver/dev/chardevicedriver1 starting\n");
printf("1,press 'o' to oprate device\n");
printf("2,press key 'q' to exit\n");
ch = getchar();
getchar();
if(ch == 'q')
{
break;
}
switch(ch)
{
case 'o':
read(fd,buf,0);
write(fd,buf,0);
ioctl(fd,0,0);
break;
default:
break;
}
sleep(1);
}
close(fd);
return 0;
}
运行结果如下: