当前位置: 技术问答>linux和unix
简单的字符设备驱动
来源: 互联网 发布时间:2016-07-16
本文导语: 错误百出 高手帮忙看看吧 #include #include #include #include #include #include #include #include #include #include #include #include #include MODULE_LICENSE("Dual BSD/GPL"); #define GLOBALMEM_SIZE 0x1000 //内存 4kb #define MEM_CLEAR 0x1 //清零内...
错误百出 高手帮忙看看吧
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
#define GLOBALMEM_SIZE 0x1000 //内存 4kb
#define MEM_CLEAR 0x1 //清零内存
#define GLOBALMEM_MAJOR 254 //预设主设备号
static int globalmem_major=GLOBALMEM_MAJOR;
struct globalmem_dev
{
struct cdev cdev;
unsigned char mem[GLOBALMEM_MAJOR];
}
struct globalmem_dev *globalmem_devp;
int globalmem_open(struct inode *inode,struct file* flip)
{
filp->private_data=globalmem_devp;
return 0;
}
int global_release(struct inode* inode,struct file *flip)
{
return 0;
}
static int globalmem_ioctl(struct inode *inodep,struct file *flip,unsigned int
cmd ,unsigned long arg)
{
struct globalmem_dev *dev=flip->private_data;
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem,0,GLOBALMEM_SIZE);
printk(KERN_INFO "globalmem is set to zero n");
break;
default:
return -EINVAL;
}
return 0;
}
//读写函数
static ssize_t globalmem_read(struct file *flip,char __user *buf,size_t
size,loff_t *ppos)
{
unsigned long p=*ppos ;
unsigned int count=size;
int ret =0;
struct globalmem_dev *dev =filp->private_data;
if(p>=GLOBALMEM_SIZE)
{
return count? -ENXIO:0;
}
if(count>GLOBALMEM_SIZE-p)
{
count=GLOBALMEM_SIZE-p;
}
if(copy_to_user(buf,(void*)(dev->mem+p),count))
{
ret=-EFAULT;
}
else
{
*ppos+=count;
ret=count;
printk(KERN_INFO "rea %d bytes(s) from %d n",count,p);
}
return ret;
}
static ssize_t globalmem_write(struct file *flip,const char __user *buf,size_t
size,loff_t *ppos)
{
unsigned long p=*ppos;
unsigned int count=size;
int ret =0;
struct globalmem_dev * dev=flip->private_data;
if(p>=GLOBALMEM_SIZE)return count? -ENXIO:0;
if(count>GLOBAL_SIZE-p)count=GLOBALMEM_SIZE-p;
if(copy_from_user(dev->mem+p,buf,count))ret=-EFAULT;
else
{
*ppos+=count;
ret=count;
printk(KEN_INFO "write %d bytes(s) from %d n",count,p);
}
return ret;
}
//seek 函数。
static loff_t globalmem_llseek(struc file *flip,loff_t offset,int orig)
{
loff_t ret=0;
switch(orig)
{
case 0:
if(offsetGLOBALMEM_SIZE)
{
ret=-EINVAL;
break;
}
flip->f_pos =(unsigned int)offset;
ret=flip->f_pos;
break;
case 1:
if((flip->f_pos+offset)>GLOBALMEM_SIZE)
{
ret=-EINVAL;
break;
}
if((flip->f_pos+offset)f_pos+=offset;
ret=flip->f_pos;
break;
default:
ret=-EINVAL;
}
return ret;
}
//ioctl()函数 用于清零
static int globalmem_ioctl(struct inode* inodep,struct file *flip,unsigned int
cmd ,unsigned long arg)
{
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem,0,GLOBALMEM_SIZE);
printk(KERN_INFO "globalmem is set to zeron");
break;
default:
return -EINVAL;//不支持其他命令
}
return 0;
}
static const struct file_operations globalmem_fops=
{
.owner=THIS_MODULE,
.llseek=globalmem_llseek,
.read=globalmem_read,
.write=globalmem_write,
.ioctl=globalmem_ioctl,
.open=globalmem_open,
.release=globalmem_release,
};
static void globalmem_setup_cdev(struct globalmem_dev *dev,int index)
{
int err,devno=MKDEV(globalmem_major,0);
cdev_init(&dev.cdev,&globalmem_fops);
dev.cdev.owner=THIS_MODULE;
dev.cdev.ops=&globalmem_fops;
err=cdev_add(&dev.cdev,devno,1);
if(err)printk(KERN_NOTICE"ERROR %d adding globalmem",err);
}
int globalmem_init(void)
{
int result;
dev_t devno=MKDEV(globalmem_major,0);
if(globalmem_major)result=register_chrdev_region(devno,1,"globalmem");
else
{
result=alloc_chrdev_region(&devno,0,1,"globalmem");
globalmem_major=MAJOR(devno);
}
if(result
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
#define GLOBALMEM_SIZE 0x1000 //内存 4kb
#define MEM_CLEAR 0x1 //清零内存
#define GLOBALMEM_MAJOR 254 //预设主设备号
static int globalmem_major=GLOBALMEM_MAJOR;
struct globalmem_dev
{
struct cdev cdev;
unsigned char mem[GLOBALMEM_MAJOR];
}
struct globalmem_dev *globalmem_devp;
int globalmem_open(struct inode *inode,struct file* flip)
{
filp->private_data=globalmem_devp;
return 0;
}
int global_release(struct inode* inode,struct file *flip)
{
return 0;
}
static int globalmem_ioctl(struct inode *inodep,struct file *flip,unsigned int
cmd ,unsigned long arg)
{
struct globalmem_dev *dev=flip->private_data;
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem,0,GLOBALMEM_SIZE);
printk(KERN_INFO "globalmem is set to zero n");
break;
default:
return -EINVAL;
}
return 0;
}
//读写函数
static ssize_t globalmem_read(struct file *flip,char __user *buf,size_t
size,loff_t *ppos)
{
unsigned long p=*ppos ;
unsigned int count=size;
int ret =0;
struct globalmem_dev *dev =filp->private_data;
if(p>=GLOBALMEM_SIZE)
{
return count? -ENXIO:0;
}
if(count>GLOBALMEM_SIZE-p)
{
count=GLOBALMEM_SIZE-p;
}
if(copy_to_user(buf,(void*)(dev->mem+p),count))
{
ret=-EFAULT;
}
else
{
*ppos+=count;
ret=count;
printk(KERN_INFO "rea %d bytes(s) from %d n",count,p);
}
return ret;
}
static ssize_t globalmem_write(struct file *flip,const char __user *buf,size_t
size,loff_t *ppos)
{
unsigned long p=*ppos;
unsigned int count=size;
int ret =0;
struct globalmem_dev * dev=flip->private_data;
if(p>=GLOBALMEM_SIZE)return count? -ENXIO:0;
if(count>GLOBAL_SIZE-p)count=GLOBALMEM_SIZE-p;
if(copy_from_user(dev->mem+p,buf,count))ret=-EFAULT;
else
{
*ppos+=count;
ret=count;
printk(KEN_INFO "write %d bytes(s) from %d n",count,p);
}
return ret;
}
//seek 函数。
static loff_t globalmem_llseek(struc file *flip,loff_t offset,int orig)
{
loff_t ret=0;
switch(orig)
{
case 0:
if(offsetGLOBALMEM_SIZE)
{
ret=-EINVAL;
break;
}
flip->f_pos =(unsigned int)offset;
ret=flip->f_pos;
break;
case 1:
if((flip->f_pos+offset)>GLOBALMEM_SIZE)
{
ret=-EINVAL;
break;
}
if((flip->f_pos+offset)f_pos+=offset;
ret=flip->f_pos;
break;
default:
ret=-EINVAL;
}
return ret;
}
//ioctl()函数 用于清零
static int globalmem_ioctl(struct inode* inodep,struct file *flip,unsigned int
cmd ,unsigned long arg)
{
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem,0,GLOBALMEM_SIZE);
printk(KERN_INFO "globalmem is set to zeron");
break;
default:
return -EINVAL;//不支持其他命令
}
return 0;
}
static const struct file_operations globalmem_fops=
{
.owner=THIS_MODULE,
.llseek=globalmem_llseek,
.read=globalmem_read,
.write=globalmem_write,
.ioctl=globalmem_ioctl,
.open=globalmem_open,
.release=globalmem_release,
};
static void globalmem_setup_cdev(struct globalmem_dev *dev,int index)
{
int err,devno=MKDEV(globalmem_major,0);
cdev_init(&dev.cdev,&globalmem_fops);
dev.cdev.owner=THIS_MODULE;
dev.cdev.ops=&globalmem_fops;
err=cdev_add(&dev.cdev,devno,1);
if(err)printk(KERN_NOTICE"ERROR %d adding globalmem",err);
}
int globalmem_init(void)
{
int result;
dev_t devno=MKDEV(globalmem_major,0);
if(globalmem_major)result=register_chrdev_region(devno,1,"globalmem");
else
{
result=alloc_chrdev_region(&devno,0,1,"globalmem");
globalmem_major=MAJOR(devno);
}
if(result