1. 程式人生 > >讀寫檔案節點---echo與read、write均可

讀寫檔案節點---echo與read、write均可

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>



MODULE_LICENSE("GPL");

#define DEVICE_NAME ("my_dev")
#define GLOBALMEM_SIZE    512    /*全域性記憶體最大4K位元組*/


int MAJOR_NUM = 666;
char g_val[20];
struct device *dev;
struct class *myclass;


static ssize_t global_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
	int ret;
	char val[20];
	printk(KERN_ERR "###### global_read \n");
	
	sprintf(val, "%s\n", g_val);
	//ssize_t simple_read_from_buffer(void __user *to, size_t count,loff_t *ppos, const void *from, size_t available);
	ret = simple_read_from_buffer(buf, len, off, val, strlen(val));
	return ret;
}

static ssize_t global_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
	int  ret = 0;
	char val[20];	
	int i =0, j = 0;
	unsigned long p = *off;
	unsigned int count = len;

	memset(val, 0, 20);
	
	/*分析和獲取有效的寫長度*/
	if (p >= GLOBALMEM_SIZE)
	{
		return count ?  - ENXIO: 0;		
	}
	if (count > GLOBALMEM_SIZE - p)
	{
		count = GLOBALMEM_SIZE - p;
	}
	
	if(copy_from_user(val, buf, count))
	{
		ret = -EFAULT;
	}
	else
	{
		*off += count;
		ret = count;
	}	
	memset(g_val, 0, 20);
	
	for(i = 0; i < strlen(val); i++)
	{
		if(val[i] >= '0' && val[i] <= '9')
		{
			g_val[j] = val[i];
			j++;
		}
	}	
	return ret;
}

struct file_operations fileops = {
	.read = global_read,
	.write = global_write,
};

static int __init globalvar_init(void)
{
	int ret;
	memset(g_val, 0, 20);
	
	printk(KERN_ERR "golabvar_init \n");
	
	ret = register_chrdev(MAJOR_NUM, "my_driver", &fileops);
	if(ret)
	{
		printk(KERN_ERR "register_chrdev fail \n");
	}
	else
	{
		printk(KERN_ERR "register_chrdev sucess \n");
		//註冊一個類,使mdev可以在"/dev/"目錄下 面建立裝置節點
		myclass = class_create(THIS_MODULE, DEVICE_NAME);
		//建立一個裝置節點,節點名為DEVICE_NAME
		dev = device_create(myclass, NULL, MKDEV(MAJOR_NUM, 0), NULL, DEVICE_NAME);
		if(!dev)
		{
			printk(KERN_ERR "device_create faile \n");
		}
		
	}	
	
	return 0;
} 

static void __exit globalvar_exit(void)
{
	printk("golabvar_exit \n");
	device_destroy(myclass, MKDEV(MAJOR_NUM, 0));
	class_destroy(myclass);
	unregister_chrdev(MAJOR_NUM, "globalvar");
}

module_init(globalvar_init);
module_exit(globalvar_exit);