- 论坛徽章:
- 0
|
#ifndef _KERNEL_
#define _KERNEL_
#endif
#ifndef MODULE
#define MODULE
#endif
#include linux/config.h
#include linux/module.h
MODULE_LICENSE("GPL");
#include asm/uaccess.h
#include linux/fs.h
#include linux/kernel.h
#include linux/types.h
#include linux/slab.h
#include linux/init.h
static int scull_open(struct inode *inode,struct file *file);
static int scull_release(struct inode *inode,struct file *file);
static ssize_t scull_read(struct file *filp,char *buf, size_t count,loff_t *f_pos);
static ssize_t scull_write(struct file *filp,const char *buf, size_t count,loff_t *f_pos);
static loff_t scull_lseek(struct file *file,loff_t offset,int orig);
struct file_operations scull_fops=
{
open:scull_open,
release: scull_release,
read:scull_read,
write:scull_write,
llseek:scull_lseek,
};
static int scull_major=0;
static int scull_size=4096;
static u7 *scull_body;
static int scull_init()
{
int result;
printk("<1>This is a simple character device driver!\n");
result=register_chrdev(scull_major,"scull",&scull_fops);
if(result<0)
return result;
if(scull_major==0)
scull_major=result;
scull_body=kmalloc(scull_size,GFP_DERNEL);
if(!scull_body)
{
result=-ENOMEM;
unregister_chrdev(scull_major,"scull");
return result;
}
memset(scull_body,0,scull_size);
printk("the major is:%d\n",scull_major);
return 0;
}
static void scull_exit()
{
unregister_chrdev(scull_major,"scull");
dfree(scull_body);
printk("A simple device has been removed!\n");
}
static int scull_open(struct inode *inode,struct file *filp)
{
MOD_INC_USE_COUNT;
return 0;
}
static int scull_release(struct inode *inode,struct file *filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t scull_read(struct file *filp,char *buf,size_t count,loff_t *f_pos)
{
loff_t pos;
pos = *f_pos;
if( ( pos==scull_size) )|| (count>scull_size) )
return 0;
pos+=count;
if( pos>scull_size)
{
count -= ( pos - scull_size);
pos = scull_size;
}
if(copy_to_user(buf,scull_body+ *f_pos,count) )
return -EFAULT;
*f_pos=pos;
return count;
}
static ssize_t scull_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos)
{
loff_t pos;
pos= *f_pos;
if( (pos==scull_size) || (count>scull_size) )
return 0;
pos += count;
if(pos>scull_size)
{
count -= ( pos - scull_size);
pos = scull_size;
}
if(copy_from_user(scull_body+ *f_pos,buf,count) )
return -EFAULT;
*f_pos=pos;
return count;
}
static loff_t scull_lseek(struct file *file,loff_t offset,int orig)
{
loff_t pos;
pos = file->f_pos;
switch(orig)
{
case 0:
pos = offset;
break;
case 1:
pos+=offset;
break;
case 2:
pos=scull_size+offset;
break;
default:
return -EINVAL;
}
if( (pos>scull_size)||(pos<0) )
{
printk("lseek() error %d\n",pos);
return -EINVAL;
}
return file->f_pos = pos;
}
module_init(scull_init);
module_exit(scull_exit);
/**********************测试函数源代码*****************************/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<error.h>
#include<fcntl.h>
#include<sys/types.h>
int main()
{
int fd,len;
char inbuf[20]="hello world!";
char outbuf[20];
fd=open("/dev/chrdev",O_WRONLY);
if(fd<0)
{
printf("error opening device for wrinting!\n");
exit(1)
}
len=write(fd,inbuf,strlen(inbuf));
if(len<0)
{
printf("error writing from device!\n");
close(fd);
exit(1);
}
printf("\n there are %d bytes written to device!\n",len);
colse(fd);
fd=open("/dev/chrdev",O_RDONLY);
if(len<0)
{
printf("error opening device for reading!\n");
exit(1);
}
len=read(fd,outbuf,len);
if(len<0)
{
printf("error reading from device!\n");
close(fd);
exit(1);
}
printf("\n there are %d byte read from device!\n",len);
}
大家帮忙调试一下,谢谢,联系方式 邮箱fumei523@163.com ,QQ360080574 |
|