讀寫檔案節點---echo與read、write均可
阿新 • • 發佈:2019-02-19
#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);