#include <linux/init.h> /* __init __exit */ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* printk() */ #include <linux/config.h> /*configuration generated when you configure your linux kernel source*/ #include <linux/fs.h> /* file_operation */ #include <asm/uaccess.h> /* copy_to_user, copy_from_user */ #include <linux/devfs_fs_kernel.h> /* devfs_mk_dir, devfs_register, devfs_regster_chrdev*/
/* KERN_EMERG 用于紧急事件,一般是系统崩溃前的提示信息 KERN_ALERT 用于需要立即采取动作的场合 KERN_CRIT 临界状态,通常设计验证的硬件或软件操作失败 KERN_ERR 用于报告错误状态.设备驱动程序通常会用它报告来自硬件的问题 KERN_WARNING 就可能出现的问题提出警告.这些问题通常不会对系统造成严重破坏 KERN_NOTICE 有必要提示的正常情况.许多安全相关的情况用这个级别汇报 KERN_INFO 提示性信息.有很多驱动程序在启动时用这个级别打印相关信息 KERN_DEBUG 用于调试的信息 */
MODULE_LICENSE("GPL");
#define MAJOR_NUM 249 //主设备号(在开发板终端输入命令'cat /proc/devices'查看,挑一个可用的即可)
static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*); static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
/*初始化字符设备驱动的file_operations结构体*/ struct file_operations globalvar_fops = { read: globalvar_read, write: globalvar_write, };
/* Module Init & Exit function */ static int global_var = 0; /*"globalvar"设备的全局变量*/ #ifdef CONFIG_DEVFS_FS
// devfs_handle_t devfs_myDriver_dir
devfs_handle_t devfs_myDriver_raw; #endif static int __init globalvar_init(void) { int ret; #ifdef CONFIG_DEVFS_FS ret = devfs_register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops); //devfs_myDriver_dir = devfs_mk_dir(NULL, "globalvar2", NULL);
devfs_myDriver_raw = devfs_register(NULL,"globalvar", DEVFS_FL_DEFAULT, MAJOR_NUM, 0, S_IFCHR | S_IRUSR | S_IWUSR, &globalvar_fops, NULL); printk("add dev file to devfs OK!\n"); #else /*注册设备驱动*/ ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops); if (ret) { printk("globalvar register failure"); } else { printk("globalvar register success"); } #endif return ret; }
static void __exit globalvar_exit(void) { int ret;
#ifdef CONFIG_DEVFS_FS ret = devfs_unregister_chrdev(MAJOR_NUM, "globalvar"); devfs_unregister(devfs_myDriver_raw); //devfs_unregister(devfs_myDriver_dir);
printk("delete dev file from devs OK!\n"); #else /*注销设备驱动*/ ret = unregister_chrdev(MAJOR_NUM, "globalvar"); if (ret) { printk("globalvar unregister failure"); } else { printk("globalvar unregister success"); } #endif
}
static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off) { /*将global_var从内核空间复制到用户空间*/ if (copy_to_user(buf, &global_var, sizeof(int))) { return - EFAULT; } return sizeof(int); }
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off) { /*将用户空间的数据复制到内核空间的global_var*/ if (copy_from_user(&global_var, buf, sizeof(int))) { return - EFAULT; } return sizeof(int); }
module_init(globalvar_init); module_exit(globalvar_exit);
|