linux字符设备驱动中自动创建设备节点【转】

来自:http://blog.csdn.net/smilefyx/article/details/40402603

简述

本文简述在Linux字符设备驱动编程中自动创建设备节点。以下内容不在本文描述范围内:

1、设备号、驱动等概念性问题;

      相关内容请看:http://blog.csdn.net/zjjyliuweijie/article/details/7001383

2、设备号的自动分配和手动指定;

      相关内容请看:http://blog.csdn.net/zhuky/article/details/5193675

3、mknode手动创建节点。

      相关内容请自行搜索mknode等相关知识。


编码实现

1、核心点

要使的驱动能够在加载时自动完成设备节点的注册,主要流程如下:

驱动加载时完成如下工作:分配设备号-------------注册字符设备------------动态创建设备节点。

驱动卸载时完成如下工作:删除设备节点-------------取消字符设备的注册-----------删除设备号。


2、例子

如下驱动简要介绍一个自动创建设备节点的驱动实例,编译驱动后加载该驱动,将在/dev目录下面生成driver_wrbuff的文件节点(宏DEVICE_NAME指定的名字)。

writebuffer.c

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <linux/module.h>  
  2. #include <linux/kernel.h>  
  3. #include <linux/fs.h>  
  4. #include <linux/init.h>  
  5. #include <linux/delay.h>  
  6. #include <asm/uaccess.h>  
  7. #include <asm/irq.h>  
  8. #include <asm/io.h>  
  9. #include <mach/gpio.h>  
  10. #include <mach/hardware.h>  
  11. #include <linux/device.h>  
  12. #include <linux/cdev.h>  
  13.   
  14. #define CHRDEV_NAME      "driver_wrbuff"  
  15. #define CLASS_NAME       "class_wrbuff"                     //表示在/system/class目录下创建的设备类别目录  
  16. #define DEVICE_NAME      "driver_wrbuff"                    //<span><span class="comment">在/dev/目录和/sys/class/class_wrbuff目录下分别创建设备文件driver_wrbuff</span><span></span></span>  
  17.   
  18. static dev_t         devt_wrbuffer;  
  19. static struct cdev*  cdev_wrbuffer;  
  20. static struct class* class_wrbuffer;  
  21.   
  22.   
  23. static int wrbuffer_open(struct inode *inode,struct file *file);  
  24. static ssize_t wrbuffer_read(struct file *file, char __user *buf, size_t count, loff_t *offset);  
  25. static ssize_t wrbuffer_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);  
  26.   
  27.   
  28. static struct file_operations fops_wrbuffer = {  
  29.    .owner = THIS_MODULE,  
  30.    .open = wrbuffer_open,  
  31.    .read = wrbuffer_read,  
  32.    .write = wrbuffer_write,  
  33. };  
  34.   
  35. static int wrbuffer_open(struct inode *inode,struct file *file)  {  
  36.     printk("open write and buffer device!");  
  37.         return 0;  
  38. }  
  39.   
  40.   
  41. static ssize_t wrbuffer_read(struct file *file, char __user *buf, size_t count, loff_t *offset)  {  
  42.     printk("write buffer device!");  
  43.     return 0;  
  44. }  
  45.   
  46. static ssize_t wrbuffer_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)  {  
  47.     printk("read buffer device!");  
  48.     return 0;  
  49. }  
  50.   
  51.   
  52. static int __init wrbuffer_init(void)  {  
  53.     int ret;  
  54.       
  55.     /*1、申请设备号*/  
  56.     ret = alloc_chrdev_region(&devt_wrbuffer,0,1,CHRDEV_NAME);  
  57.     if(ret)  {  
  58.         printk("alloc char driver error!\n");  
  59.         return ret;  
  60.     }  
  61.       
  62.     /*2、注册字符设备*/  
  63.     cdev_wrbuffer = cdev_alloc();  
  64.     cdev_init(cdev_wrbuffer,&fops_wrbuffer);  
  65.     cdev_wrbuffer->owner = THIS_MODULE;  
  66.     ret = cdev_add(cdev_wrbuffer,devt_wrbuffer,1);  
  67.     if(ret)  {  
  68.         printk("cdev create error!\n");  
  69.         unregister_chrdev_region(devt_wrbuffer,1);  
  70.         return ret;  
  71.     }  
  72.       
  73.     /*3、创建设备节点*/  
  74.     class_wrbuffer = class_create(THIS_MODULE,CLASS_NAME);  
  75.     device_create(class_wrbuffer,NULL,devt_wrbuffer,NULL,DEVICE_NAME);  
  76.       
  77.     printk("wrbuffer driver init is ok!\n");  
  78.   
  79.     return 0;  
  80. }  
  81.   
  82. static void __exit wrbuffer_exit(void) {  
  83.     /*1、删除设备节点*/  
  84.     device_destroy(class_wrbuffer,devt_wrbuffer);  
  85.     class_destroy(class_wrbuffer);  
  86.       
  87.     /*2、取消字符设备注册*/  
  88.     cdev_del(cdev_wrbuffer);  
  89.       
  90.     /*3、释放设备号*/  
  91.     unregister_chrdev_region(devt_wrbuffer,1);  
  92. }  
  93.   
  94.   
  95. late_initcall(wrbuffer_init);  
  96. module_exit(wrbuffer_exit);  
  97.   
  98. MODULE_AUTHOR("yxtouch520@yeah.net");  
  99. MODULE_DESCRIPTION("allwinner buffer read and write test driver");  
  100. MODULE_LICENSE("GPL");  

3、Makefile

使用如下Makefile文件进行驱动模块的编译,请按照自己需要配置内核路径。

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. obj-m := sun7i_wrbuffer.o  
  2. sun7i_wrbuffer-objs := writebuffer.o  
  3. KERNELDIR := /home/feiyinxian/workspace/A20/landsem/A20_Android4.4/lichee/linux-3.4  
  4. PWD := $(shell pwd)  
  5.   
  6. modules:  
  7.         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  
  8. .PHONY:clean  
  9. clean:  
  10.         rm *.ko *.o  
修改内核路径后输入make即可编译生成驱动模块,拷贝编译生成的模块到目标板,使用insmod加载模块,查看/dev/目录下面是否成功创建设备节点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值