GLOBDEV——linux字符设备驱动程序

#include"linux/module.h"
#include"linux/types.h"
#include"linux/fs.h"
#include"linux/errno.h"
#include"linux/mm.h"
#include"linux/sched.h"
#include"linux/init.h"
#include"linux/cdev.h"
#include"asm/io.h"
#include"asm/system.h"
#include"asm/uaccess.h"
#define GLOB_SIZE 0x1000  //4KB
#define MEM_CLEAR 0x01	//clear


//////function extern
static ssize_t glob_read(struct file *filep,char __user *buf,size_t count,loff_t *ppos);
static ssize_t glob_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos);
static void glob_setup_cdev();
static int glob_init(void);
static void glob_exit();


///struct 
struct glob_dev{
				struct cdev cdev;
				unsigned char mem[GLOB_SIZE];
};
struct file_operations glob_file_operations={
				.owner=THIS_MODULE,
				.read=glob_read,
				.write=glob_write,				
};


static struct glob_dev dev;
static int glob_major;
static dev_t devnumber;



static int glob_init(void)
{	
	int result=alloc_chrdev_region(&devnumber,0,1,"GLOBDEV");
	if(result<0)
		{
		printk("<0>alloc_chrdev_region is return number is %d!\n",result);
		return result;
		}
	glob_major=MAJOR(devnumber);
	glob_setup_cdev();
	return 0;	
}
static void glob_exit()
{
	cdev_del(&dev.cdev);
	unregister_chrdev_region(devnumber,1);	
}
static void glob_setup_cdev()
{
	int err;
	cdev_init(&(dev.cdev),&glob_file_operations); //cdev与file_operations建立关系
	dev.cdev.owner=THIS_MODULE;	//	
	err=cdev_add(&dev.cdev,devnumber,1);  //添加cdev设备
	if(err)
		printk("<0> cdev_add is ERROR!\n");
}
static ssize_t glob_read(struct file *filep,char __user *buf,size_t count,loff_t *ppos)
{
	loff_t p=*ppos;
	unsigned long int ret;
	///////处理越界问题。
	if(p>=GLOB_SIZE)
		return 0;
	if(count>GLOB_SIZE-p)
		count=GLOB_SIZE-p;
		
	if((ret=copy_to_user(buf,(void *)(dev.mem+p),count)))
		{
			printk("<0>success is %ld,faild is %ld!\n",count-ret,ret);
		}
	else
		{
			printk("<0>success is %ld,faild is %ld!\n",count-ret,ret);
			*ppos+=count;
			ret=count;
		}	
		return (ssize_t)ret;		
}

static ssize_t glob_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos)
{
	loff_t p=*ppos;
	unsigned long int ret;
	
	///////处理越界问题。
	if(p>GLOB_SIZE)
		return 0;
	if(count>GLOB_SIZE-p)
		count=GLOB_SIZE-p;
	
	if((ret=copy_from_user((void *)(dev.mem+p),buf,count)))
		{
			printk("<0>success is %ld,faild is %ld!\n",count-ret,ret);
		}	
	else 	
		{
			printk("<0>success is %ld,faild is %ld!\n",count-ret,ret);	
			*ppos+=count;
			ret=count;
		}	
	return (ssize_t)ret;
}
module_init(glob_init);
module_exit(glob_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("a linux device drivers");
MODULE_VERSION("1.0");

学习编写linux驱动程序的时候,我遇到的错误如下:

1.本来是loff_t 错写为lofft ,

2.填充file_operations的时候,应该是.owner     .read   .write  的后面是逗号,我写成了分号。

猜你喜欢

转载自blog.csdn.net/snikeguo/article/details/28431811