当前位置: 技术问答>linux和unix
新手驱动问题
来源: 互联网 发布时间:2016-06-22
本文导语: 驱动程序: #include #include #include #include #include #include #include #include #include #include #include #define MEM_CLEAR 0 #define MEM_RE 1 #define MEM_SETSIZE 2 #define GLOBALMEM_SIZE 0x1000 #define GLOBALMEM_MAJOR 255 struct globalmem_...
驱动程序:
测试程序
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MEM_CLEAR 0
#define MEM_RE 1
#define MEM_SETSIZE 2
#define GLOBALMEM_SIZE 0x1000
#define GLOBALMEM_MAJOR 255
struct globalmem_dev
{
unsigned int count;
unsigned int size;
struct cdev cd;
unsigned char mem[GLOBALMEM_SIZE];
};
struct globalmem_dev *g_dev;
struct file_operations globalmem_fopes;
int globalmem_major=GLOBALMEM_MAJOR;
int globalmem_open(struct inode *inode,struct file *filp)
{
filp->private_data=g_dev;
g_dev->count++;
return 0;
}
int globalmem_release(struct inode *inode,struct file *filp)
{
if(g_dev->count>0)
g_dev->count--;
return 0;
}
int globalmem_ioctl(struct inode *inodep,
struct file *filp,unsigned int cmd,unsigned long arg)
{
int i;
char c;
switch(cmd)
{
case MEM_CLEAR:
memset(g_dev->mem,0,g_dev->count);
printk(KERN_INFO "globalmem is set to zeron");
break;
case MEM_RE:
if(g_dev->count!=1)
return -1;
for(i=0;isize/2;i++){
c=g_dev->mem[i];
g_dev->mem[i]=g_dev->mem[g_dev->size-i-1];
g_dev->mem[g_dev->size-i-1]=c;
}
break;
case MEM_SETSIZE:
if(argGLOBALMEM_SIZE)
break;
g_dev->size=arg;
break;
default:
return -1;
}
return 0;
}
int globalmem_read(struct file *filp,char __user *buf,
size_t size,loff_t *ppos)
{
unsigned long pos=*ppos;
unsigned long count=size;
printk(KERN_INFO "readn");
printk("%cn",g_dev->mem[0]);
if(access_ok(VERIFY_WRITE,buf,count)==-EFAULT)
{
printk(KERN_INFO "read error1n");
return -EFAULT;
}
if(*ppos+count>g_dev->size)
count=g_dev->size-(*ppos);
if(copy_to_user(buf,(void*)(g_dev->mem+pos),count))
{
printk(KERN_INFO "read error2n");
return -EFAULT;
}
*ppos+=count;
printk("%sn",g_dev->mem);
printk(KERN_INFO "read overn");
return count;
}
int globalmem_write(struct file *filp,char __user *buf,
size_t size,loff_t *ppos)
{
printk(KERN_INFO "writen");
printk("%cn",g_dev->mem[0]);
if(g_dev->count!=1)
{
printk(KERN_INFO "write error:g_dev!=1n");
return -EFAULT;
}
unsigned long real_size;
if(size+(g_dev->size) > GLOBALMEM_SIZE)
real_size=GLOBALMEM_SIZE;
else
real_size=size;
if(copy_from_user((g_dev->mem)+real_size,(void *)buf,real_size))
{
printk(KERN_INFO "write error 1n");
return -EFAULT;
}
g_dev->size+=real_size;
printk("%sn",g_dev->mem);
printk(KERN_INFO "write overn");
return real_size;
}
loff_t globalmem_llseek(struct file *filp,loff_t offset,int orig)
{
switch(orig)
{
case 0://from the begin of the file
if(offset GLOBALMEM_SIZE)
return -EFAULT;
filp->f_pos=(unsigned int)offset;
return offset;
case 1://from the current of the file
if(filp->f_pos+offset>GLOBALMEM_SIZE || filp->f_pos+offsetf_pos+=offset;
return filp->f_pos;
case 2://from the end of the file
if(offset>0 || offset+g_dev->sizef_pos=(unsigned int)(offset+g_dev->size);
return filp->f_pos;
default:
return -EFAULT;
}
}
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,index);
cdev_init(&g_dev->cd,&globalmem_fops);
g_dev->cd.owner=THIS_MODULE;
g_dev->cd.ops=&globalmem_fops;
err=cdev_add(&g_dev->cd,devno,1);
if(err)
printk(KERN_NOTICE "Error %d adding LED%d", err, index);
}
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(resultsize=0;
g_dev->count=0;
globalmem_setup_cdev(g_dev,0);
return 0;
}
void globalmem_exit(void)
{
cdev_del(&g_dev->cd);
kfree(g_dev);
unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);
}
MODULE_AUTHOR("BLACK & WHITE");
MODULE_LICENSE("Dual BSD/GPL");
module_param(globalmem_major, int, S_IRUGO);
module_init(globalmem_init);
module_exit(globalmem_exit);
测试程序
#include
#include
#include
#include
void main()
{
int testdev;
int i;
char buf[21];
char wbuf[22]="shuchuanyushuchundfdd";
testdev=open("/dev/test",O_RDWR);
if ( testdev == -1 )
{
printf("Cann't open file n");
exit(0);
}
int w=write(testdev,wbuf,21);
//printf("buf:%sn",wbuf);
printf("%in",w);
read(testdev,buf,21);
//for (i = 0; i