标题:
手动和自动注册获取设备号和节点
[打印本页]
作者:
yuyang911220
时间:
2017-1-25 21:15
标题:
手动和自动注册获取设备号和节点
内核:2.6.32.2
一、
手动注册设备号
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/device.h>
#define DEVICE_NAME "find_button" //
设备名字
static int DEVICE_NAME_drv_open(struct inode *inode, struct file *file)
{
return 0;
}
ssize_t DEVICE_NAME_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static struct file_operations DEVICE_NAME_drv_fops = { //
驱动核心结构
.owner = THIS_MODULE, //
宏
.open = DEVICE_NAME_drv_open,
.read = DEVICE_NAME_drv_read,
};
int major=111; //
自定义设备号
static int DEVICE_NAME_drv_init(void) //
设备加载调用函数
{
int ret;
ret=register_chrdev(major, DEVICE_NAME, &DEVICE_NAME_drv_fops);
if(ret<0) //
根据返回值判断是否注册成功
printk(DEVICE_NAME "initialized failed\n");
else
printk(DEVICE_NAME "initialized success\n");
return ret;
}
static void DEVICE_NAME_drv_exit(void) //
卸载设备时调用的函数
{
unregister_chrdev(major, DEVICE_NAME );//
设备号,设备名字
printk(DEVICE_NAME "uninstalled success\n");
}
module_init(DEVICE_NAME_drv_init);//
用来修饰
_init
和
_exit
函数
module_exit(DEVICE_NAME_drv_exit);
MODULE_LICENSE("GPL");
二、自动注册设备号
省略头文件
内核中定义了
struct class
结构体,顾名思义,一个
struct class
结构体类型变量对应一个类,内核同时提供了
class_create(…)
函数,可以用它来创建一个类,这个类存放于
sysfs
下面,一旦创建好了这个类,再调用
device_create(…)
函数来在
/dev
目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的
udev
会自动响应
device_create(…)
函数,去
/sysfs
下寻找对应的类从而创建设备节点。
static struct class *my_class; //
定义一个类,用来自动获取设备号
static struct class_device *my_class_dev //
在定义的类下定义一个设备
#define DEVICE_NAME "find_button" //
宏定义设备名字
static int DEVICE_NAME_drv_open(struct inode *inode, struct file *file)
{
return 0;
}
ssize_t DEVICE_NAME_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static struct file_operations DEVICE_NAME_drv_fops = {
.owner = THIS_MODULE,
.open = DEVICE_NAME_drv_open,
.read = DEVICE_NAME_drv_read,
}; //
不要忘记冒号
int major; //
定义变量用来表示设备号
static int DEVICE_NAME_drv_init(void) //
注册设备时调用函数
{
major=register_chrdev(0, DEVICE_NAME, &DEVICE_NAME_drv_fops);
//
创建类,参数:模块拥有者,指定类名
my_class=class_create(THIS_MODULE, DEVICE_NAME);
my_class_dev=device_create(my_class, NULL, MKDEV(major, 0), NULL,DEVICE_NAME);
printk(DEVICE_NAME "installed success\n");
return 0;
}
static void DEVICE_NAME_drv_exit(void)
{
unregister_chrdev(major, DEVICE_NAME)
;
//
卸载设备驱动函数
device_destroy(my_class,MKDEV(major, 0));//
删除设备节点
class_destroy(my_class); //
删除创建的类
printk(DEVICE_NAME "uninstalled success\n");
}
module_init(DEVICE_NAME_drv_init);
module_exit(DEVICE_NAME_drv_exit);
MODULE_LICENSE("GPL");
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0