简述
本文简述在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
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/gpio.h>
#include <mach/hardware.h>
#include <linux/device.h>
#include <linux/cdev.h>
#define CHRDEV_NAME "driver_wrbuff"
#define CLASS_NAME "class_wrbuff" //表示在/system/class目录下创建的设备类别目录
#define DEVICE_NAME "driver_wrbuff" //<span><span class="comment">在/dev/目录和/sys/class/class_wrbuff目录下分别创建设备文件driver_wrbuff</span><span></span></span>
static dev_t devt_wrbuffer;
static struct cdev* cdev_wrbuffer;
static struct class* class_wrbuffer;
static int wrbuffer_open(struct inode *inode,struct file *file);
static ssize_t wrbuffer_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
static ssize_t wrbuffer_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
static struct file_operations fops_wrbuffer = {
.owner = THIS_MODULE,
.open = wrbuffer_open,
.read = wrbuffer_read,
.write = wrbuffer_write,
};
static int wrbuffer_open(struct inode *inode,struct file *file) {
printk("open write and buffer device!");
return 0;
}
static ssize_t wrbuffer_read(struct file *file, char __user *buf, size_t count, loff_t *offset) {
printk("write buffer device!");
return 0;
}
static ssize_t wrbuffer_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) {
printk("read buffer device!");
return 0;
}
static int __init wrbuffer_init(void) {
int ret;
/*1、申请设备号*/
ret = alloc_chrdev_region(&devt_wrbuffer,0,1,CHRDEV_NAME);
if(ret) {
printk("alloc char driver error!\n");
return ret;
}
/*2、注册字符设备*/
cdev_wrbuffer = cdev_alloc();
cdev_init(cdev_wrbuffer,&fops_wrbuffer);
cdev_wrbuffer->owner = THIS_MODULE;
ret = cdev_add(cdev_wrbuffer,devt_wrbuffer,1);
if(ret) {
printk("cdev create error!\n");
unregister_chrdev_region(devt_wrbuffer,1);
return ret;
}
/*3、创建设备节点*/
class_wrbuffer = class_create(THIS_MODULE,CLASS_NAME);
device_create(class_wrbuffer,NULL,devt_wrbuffer,NULL,DEVICE_NAME);
printk("wrbuffer driver init is ok!\n");
return 0;
}
static void __exit wrbuffer_exit(void) {
/*1、删除设备节点*/
device_destroy(class_wrbuffer,devt_wrbuffer);
class_destroy(class_wrbuffer);
/*2、取消字符设备注册*/
cdev_del(cdev_wrbuffer);
/*3、释放设备号*/
unregister_chrdev_region(devt_wrbuffer,1);
}
late_initcall(wrbuffer_init);
module_exit(wrbuffer_exit);
MODULE_AUTHOR("yxtouch520@yeah.net");
MODULE_DESCRIPTION("allwinner buffer read and write test driver");
MODULE_LICENSE("GPL");
3、Makefile
使用如下Makefile文件进行驱动模块的编译,请按照自己需要配置内核路径。
obj-m := sun7i_wrbuffer.o
sun7i_wrbuffer-objs := writebuffer.o
KERNELDIR := /home/feiyinxian/workspace/A20/landsem/A20_Android4.4/lichee/linux-3.4
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
.PHONY:clean
clean:
rm *.ko *.o
修改内核路径后输入make即可编译生成驱动模块,拷贝编译生成的模块到目标板,使用insmod加载模块,查看/dev/目录下面是否成功创建设备节点。
---------------------
作者:yingxian_Fei
来源:CSDN
原文:https://blog.csdn.net/smilefyx/article/details/40402603
版权声明:本文为博主原创文章,转载请附上博文链接!
本文详细介绍如何在Linux字符设备驱动编程中实现设备节点的自动创建。通过具体代码示例,展示从设备号分配、字符设备注册到动态创建设备节点的全过程。并提供Makefile编译指导及模块加载验证步骤。

176

被折叠的 条评论
为什么被折叠?



