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

📄 chardev.c

📁 Linux设备管理源码 字符设备驱动程序:设计两个终端设备文件实现一个字符设备驱动程序
💻 C
字号:
/**************************************************************/
/***** chardev.c *****/
/**************************************************************/
#ifndef __KERNEL__#    define __KERNEL__#endif#ifndef MODULE#    define MODULE#endif#define WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE#define __NO_VERSION__#include <linux/version.h>#include <linux/module.h>char kernel_version[]=UTS_RELEASE;#include <linux/kernel.h>#include <linux/mm.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/string.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/uaccess.h>

#include "chardev.h"

#define DEVICE_NAME "dynchar"static int usage,new_msg;       // control flags
static char *data;// open the device
    static int dynchar_open(struct inode *inode,struct file *filp) {	    MOD_INC_USE_COUNT;	    printk("This chrdev is in open!\n");	    return 0;	}
// close the device
	static int dynchar_release(struct inode *inode,struct file *filp) {
		MOD_DEC_USE_COUNT;
		printk("This chrdev is in release!\n");
		return 0;
	}

// write to device -transfer from user space to kernel space    static ssize_t dynchar_write(struct file *filp,const char *buf,
size_t count,loff_t *offset) {		if(count<0)			return -EINVAL;		if(usage || new_msg)			return -EBUSY;	    usage=1;        kfree(data);		data=kmalloc(sizeof(char)*(count+1),GFP_KERNEL);		if(!data) {			return -ENOMEM;		}		copy_from_user(data,buf,count+1);   // start transfering		usage=0;		new_msg=1;		return count;	}	// read from device -transfer from kernel space to user space	static ssize_t dynchar_read(struct file *filp,char *buf,size_t count,
loff_t *offset) {		int length;		if(count<0)			return -EINVAL;		if(usage)			return -EBUSY;		usage=1;		if(data==NULL)			return 0;		length=strlen(data);		if(length<count)			count=length;		copy_to_user(buf,data,count+1);    // start transfering		new_msg=0;		usage=0;		return count;	}// ioctl for device -control or set the device	static int dynchar_ioctl(struct inode *inode,struct file *filp,
unsigned long int cmd,unsigned long arg) {		int ret=0;		switch(cmd) {
			case DYNCHAR_RESET;
				kfree(data);
				data=NULL;
				usage=0;
				new_msg=0;
				break;
		case DYNCHAR_QUERY_NEW_MSG:
			if(new_msg)
				return IOC_NEW_MSG;
			break;
		case DYNCHAR_QUERY_MSG_LENGTH:
			if(data==NULL) {
				return 0;
			}
			else {
				return strlen(data);
			}
			break;
		default:			return -ENOTTY;		}		return ret;	}
	struct file_operations dynchar_fops={		NULL,                 // seek		dynchar_read,         // read		dynchar_write,        // write		NULL,                 // readdir		NULL,                 // poll		dynchar_ioctl,        // ioctl		NULL,                 // mmap		dynchar_open,         // open
		NULL,                 // flush		dynchar_release,      // release		NULL,                 // fsync		NULL,                 // fasync		NULL,				  // check media change		NULL,                 // revalidate
		NULL                  // lock	};// Initialize the module -Register the character device	int init_module(){		if(register_chrdev(DYNCHAR_MAJOR,DEVICE_NAME,&dynchar_fops)) {
			printk("registering character device major: %d failed!\n",DYNCHAR_MAJOR);
			return -EIO;
		}		// initialize the data ptr
		data=NULL;
		usage=0;
		new_msg=0;		return 0;	}// Clean up -Unregister the character device	void cleanup_module() {
		// free data memory if any
		if(data)
			kfree(data);		unregister_chrdev(DYNCHAR_MAJOR,DEVICE_NAME);		printk("Sorry! The dynchar is unloading now!\n");	}		

⌨️ 快捷键说明

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