内核: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"); |