www.pudn.com > 嵌入式linux9应用开发祥解.rar > TestDriver.C


/*TestDriver.c*/ 
/*一个简单的字符设备驱动实例*/ 
#define __NO_VERSION__ 
#include  
#include  
char kernel_version [] = UTS_RELEASE; 
#define KERNEL 
#include  
#include  
#include  
#include  
#include  
#define SUCCESS 0 
static int device _read(struct inode *, struct file *, char *, int); 
static int device_open(struct inode *inode, struct file *file) 
static void device _release(struct inode *, struct file *); 
/*在fs.h中定义有与入口相关的数据结构*/ 
struct file_operations tdd_fops = 
{ 
    	NULL, 
  	 device _read, 
  	  NULL, 
   	 NULL, 
   	 NULL, 
   	 NULL, 
   	 NULL, 
  	 device _open, 
  	 device _release, 
 	   NULL, 
 	   NULL, 
 	   NULL, 
 	   NULL 
}; 
/*设备声明 ******************************** */ 
/*将出现在 /proc/devices 中设备名*/ 
#define DEVICE_NAME "char_dev" 
/*设备正打开?防止对同一设备的同时访问*/ 
static int Device_Open = 0; 
unsigned int test_major = 0; 
/*当被询问时设备将给出的消息*/ 
static char Message[BUF_LEN]; 
/*这个函数在进程试图打开设备文件时被调用*/ 
static int device_open(struct inode *inode, struct file *file){ 
		#ifdef DEBUG 
		printk ("device_open(%p)\n", file); 
		#endif 
 
		/*不想同时和两个进程对话*/ 
		if (Device_Open) 
		return -EBUSY; 
 
		Device_Open++; 
		MOD_INC_USE_COUNT; 
		return SUCCESS; 
} 
 
/*这个函数在关闭设备时调用*/ 
static void device_release(struct inode *inode, struct file *file){ 
		#ifdef DEBUG 
		printk ("device_release(%p,%p)\n", inode, file); 
		#endif 
 
/*为下个调用者做准备*/ 
		Device_Open --; 
		MOD_DEC_USE_COUNT; 
} 
/*read()入口,这个函数是为read调用准备的。当调用read时,read_test()被调用,它把用户的 
缓冲区全部写1*/ 
static int device_read (struct inode *node,struct file *file,char *buf,int count){ 
		int left; 
		if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT ) 
		return -EFAULT; 
		for(left = count ; left > 0 ; left--){ 
		/*在device_read被调用时,系统进入核心态,所以不能使用buf这个地址,而必须用_put_user(),这是kernel提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数,请参考*/ 
		_put_user(1,buf,1); 
	 	 buf++; 
		} 
		return count; 
} 
 
/*init_module向系统的字符设备表登记一个字符设备*/ 
int init_module(void) 
{ 
		int result; 
		/*注册字符设备*/ 
		result = register_chrdev(0, " char_dev", & tdd_fops); 
		if (result < 0) { 
		printk(KERN_INFO "char_dev: can't get major number\n"); 
		return result; 
		} 
/*如果登记成功,则返回0,得到设备的主设备号,如不成功,则返回一个负值*/ 
if (test_major == 0) test_major = result; 
/*安装进入内核时打印提示信息*/ 
printk("Hello,I'm in kenel mode\n"); 
 return 0; 
} 
 
void cleanup_module(void) 
{ 
printk("Hello,I'm  going to out \n"); 
unregister_chrdev(test_major, "test"); 
}