⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chardev.c

📁 在linux环境下的字符设备驱动程序。具有最基本的设备的读和写功能
💻 C
字号:
	#include <linux/kernel.h>
	#include <linux/module.h>
	#include <linux/fs.h>
	#include <asm/uaccess.h>
	#include <linux/ioctl.h>


	int init_module(void);
	void cleanup_module(void);

	static int device_open(struct inode *, struct file *);
	static int device_release(struct inode *, struct file *);

	static ssize_t device_read(struct file *, char *, size_t, loff_t *);
	static ssize_t device_write(struct file *, const char *, size_t, loff_t *);

	static int device_ioctl(struct inode *, struct file *, unsigned int, unsigned long);


	#define DEVICE_NAME "chardev"
	#define MAJOR_NUM 250 
	#define SUCCESS 0     
	#define IOCTL_SET_MSG _IOW(MAJOR_NUM, 0, int *)
	#define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, int *)

	
	static int Device_Open = 0;	static int Major;	static int arg_flag = 0;  
	static int pointer;

	static int msgx_init = 0;
	static int msgy_init = 0;
	static int msgz_init = 0;

	static int counterx = 0;
	static int countery = 0;
	static int counterz = 0;

	static char msgx[80];
	static char msgy[80];
	static char msgz[80];

	static char *msg_Ptr;      
	
	static struct file_operations fops = 
	{
		read : device_read, 
	  	write : device_write,
	  	open : device_open,
	  	release : device_release,
		ioctl : device_ioctl
	};
	
	
	int init_module(void)
	{
	   Major = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
	
	   msg_Ptr = msgx;
	  
	   if (Major < 0) 
	   {
	   	printk ("\nRegistering the character device failed with %d\n", Major);
	    	return Major;
	   }
	
	   printk("<1>\nThe device has been registered!\n");
	
	   return SUCCESS;
	}
	
	
	void cleanup_module(void)
	{
	   int ret = unregister_chrdev(MAJOR_NUM, DEVICE_NAME);

	   msg_Ptr = msgx;

	   if (ret < 0) 
	   	printk("\nError in unregister_chrdev: %d\n", ret);
	   
	   printk("<1>\nThe device has been removed!\n");
	}  
	
	
	static int device_open(struct inode *inode, struct file *file)
	{
	   if (Device_Open) 
	   	return -EBUSY;
	   
	   printk("\nDevice is open\n");

	   Device_Open++;

		if (msgx_init == 0)
                sprintf(msgx,"I already told you %d times I'm WangKai!\n", counterx);
	   if (msgy_init == 0)
                sprintf(msgy,"I already told you %d times I'm a student!\n", countery);
	   if (msgz_init == 0)
                sprintf(msgz,"I already told you %d times I'm 20 years old!\n", counterz);

	   pointer = 0;

	   return SUCCESS;
	}
	
	
	static int device_release(struct inode *inode, struct file *file)
	{
	   printk("\nDevice is closed\n");
		
	   Device_Open--;     	
	
	   return SUCCESS;
	}
	
	
	static ssize_t device_read(struct file *filp,char *buffer,
				   size_t length,loff_t *offset) 
	{
		int bytes_read = 0;

		if (pointer == 1)
			return 0;

	   printk("\nRead data from kernelspace to userspace\n");
	
	   while (length && *msg_Ptr && !pointer)  
	   {
	   	put_user(*(msg_Ptr++), buffer++);
			length--;
			bytes_read++;
	   }

	   if (arg_flag==0) {counterx++;msg_Ptr = msgx;}
	   if (arg_flag==1) {countery++;msg_Ptr = msgy;}
	   if (arg_flag==2) {counterz++;msg_Ptr = msgz;}
		pointer = 1;	

	   return bytes_read;
	}
	
	
	static ssize_t device_write(struct file *filp,const char *buffer,
		 		    size_t length,loff_t *offset)
	{
	   int bytes_write = 0;

	   if (*buffer == 0)
			return 0;

	   printk("\nWrite data from userspace to kernelspace\n");

	   while (length && *buffer)
	   {
	   	get_user(*(msg_Ptr++), buffer++);
			length--;
			bytes_write++;
	   }
	   
	   if (arg_flag==0) msgx_init = 1;
	   if (arg_flag==1) msgy_init = 1;
	   if (arg_flag==2) msgz_init = 1;
		msg_Ptr = msg_Ptr-bytes_write;
	   return bytes_write;
	}


	static int device_ioctl(struct inode *inode, struct file *file, 
				unsigned int cmd, unsigned long arg)
	{
	   switch(cmd)
	   {
		case IOCTL_SET_MSG:
			if (arg==1) {msg_Ptr=msgx;arg_flag=0;}
			if (arg==2) {msg_Ptr=msgy;arg_flag=1;}
			if (arg==3) {msg_Ptr=msgz;arg_flag=2;}
			break;
		case IOCTL_GET_MSG:
			if (msg_Ptr==msgx) *(long *)arg=1;
			if (msg_Ptr==msgy) *(long *)arg=2;
			if (msg_Ptr==msgz) *(long *)arg=3;
		default:
			break;
	   }
	   
	   return 0;
	}


	MODULE_LICENSE("GPL");
	MODULE_AUTHOR("WangKai");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -