Board logo

标题: 手动和自动注册获取设备号和节点 [打印本页]

作者: 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