设备驱动--自动创建节点

来源:互联网 发布:淘宝账号名称怎么修改 编辑:程序博客网 时间:2024/05/17 04:10
  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3. #include <linux/fs.h>  
  4. #include <linux/device.h>  
  5.   
  6. MODULE_LICENSE("GPL");  
  7.   
  8. #define DEVICE_NAME ("my_dev")  
  9.   
  10. int MAJOR_NUM = 666;  
  11. int g_val;  
  12. struct device *dev;  
  13. struct class *myclass;  
  14.   
  15. static ssize_t global_read(struct file *filp, char __user *buf, size_t len, loff_t *off)  
  16. {  
  17.     int ret;  
  18.     char val[20];  
  19.     printk(KERN_ERR "###### global_read \n");  
  20.       
  21.     sprintf(val, "%d\n", g_val);  
  22.     //ssize_t simple_read_from_buffer(void __user *to, size_t count,loff_t *ppos, const void *from, size_t available);  
  23.     ret = simple_read_from_buffer(buf, len, off, val, strlen(val));  
  24.     return ret;  
  25. }  
  26.   
  27. static ssize_t global_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)  
  28. {  
  29.     int  ret, temp;  
  30.     char val[20];  
  31.     //simple_write_to_buffer(void *to, size_t available, loff_t *ppos,const void __user *from, size_t count);  
  32.       
  33.     ret = simple_write_to_buffer(val, strlen(val), off, buf, len);  
  34.     sscanf(val, "%d", &temp);  
  35.     g_val = temp;  
  36.     return ret;  
  37. }  
  38.   
  39. struct file_operations fileops = {  
  40.     .read = global_read,  
  41.     .write = global_write,  
  42. };  
  43.   
  44. static int __init globalvar_init(void)  
  45. {  
  46.     int ret;  
  47.     g_val = 0;  
  48.       
  49.     printk(KERN_ERR "golabvar_init \n");  
  50.       
  51.     ret = register_chrdev(MAJOR_NUM, "my_driver", &fileops);  
  52.     if(ret)  
  53.     {  
  54.         printk(KERN_ERR "register_chrdev fail \n");  
  55.     }  
  56.     else  
  57.     {  
  58.         printk(KERN_ERR "register_chrdev sucess \n");  
  59.         //注册一个类,使mdev可以在"/dev/"目录下 面建立设备节点  
  60.         myclass = class_create(THIS_MODULE, DEVICE_NAME);  
  61.         //创建一个设备节点,节点名为DEVICE_NAME  
  62.         dev = device_create(myclass, NULL, MKDEV(MAJOR_NUM, 0), NULL, DEVICE_NAME);  
  63.         if(!dev)  
  64.         {  
  65.             printk(KERN_ERR "device_create faile \n");  
  66.         }  
  67.           
  68.     }     
  69.       
  70.     return 0;  
  71. }   
  72.   
  73. static void __exit globalvar_exit(void)  
  74. {  
  75.     printk("golabvar_exit \n");  
  76.     device_destroy(myclass, MKDEV(MAJOR_NUM, 0));  
  77.     class_destroy(myclass);  
  78.     unregister_chrdev(MAJOR_NUM, "globalvar");  
  79. }  
  80.   
  81. module_init(globalvar_init);  
  82. module_exit(globalvar_exit);  


makefile

[cpp] view plaincopyprint?
  1. obj-m := mknode.o      
  2. mknode-objs := auto_mknode.o     
  3.       
  4. KID :=/lib/modules/`uname -r`/build      
  5. PWD := $(shell pwd)      
  6.       
  7. all:      
  8.     make -C $(KID) M=${PWD} modules      
  9.       
  10. clean:      
  11.     rm -rf *.o .cmd *.ko *.mod.c .tmp_versions  



参考:

在2.6里已经用udev取代devfs,为解决上面那样手动创建节点的麻烦,我们可以在程序里加上创建节点这项,如下:
以字符设备char_dev为例,在驱动初始化的代码里调用class_create为该设备创建一个class,再为每个设备调用 class_device_create创建对应的设备,这样的module被加载时,undev daemon就会自动在/dev下创建char_dev设备文件。大概方法如下:
struct class *myclass = class_create(THIS_MODULE, “char_dev”);
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);

当然,在exit函数中要把创建的class移除:
class_destory(&xxx_dev->cdev);
class_device_desotry(my_class,MKDEV(major_num,0));

下面介绍下函数class_creat和class_device_creat的原型:
class_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class *class_create(struct module *owner, const char *name)
    class_create - create a struct class structure
    @owner: pointer to the module that is to "own" this struct class
    @name: pointer to a string for the name of this class.
在/sys/class/下创建类目录


class_device_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class_device *class_device_creat
(struct class        *cls,
                                         struct class_device *parent,
                                         dev_t               devt,
                                         struct device       *device,
                                         const char          *fmt, ...)

    class_device_create - creates a class device and registers it with sysfs
    @cls: pointer to the struct class that this device should be registered to.
    @parent: pointer to the parent struct class_device of this new device, if any.
    @devt: the dev_t for the char device to be added.
    @device: a pointer to a struct device that is assiociated with this class device.
    @fmt: string for the class device's name
void class_destroy(struct class *cls);/*销毁/sys/class下的类   */
void class_device_destroy(struct class *cls, dev_t devt);   /*销毁一个类设备*/
参数含义同上
补充:
在Linux2.6中,针对上面的这个问题不同的版本有些修改,使用前要先查看下/.../include/linux/device.h里的函数声明,如我用的是Linux2.6.29,里面就没有class_device_create函数,而直接使用device_create就可以了,而在之前的版本如Linux2.6.15,里面就要用class_device_create函数

原创粉丝点击