您的位置:首页 > 运维架构 > Linux

linux字符设备驱动程序框架

2014-05-12 10:05 295 查看
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/cdev.h>
#include <linux/types.h>

#define	xxx_DEVICE_COUNT	1

/*xxx字符设备结构体*/
struct xxx_dev
{
struct cdev 	cdev;
unsigned char 	*sth_of_xxx;	//预留
};
struct xxx_dev 	*xxx_dev;

/*自动创建设备节点类*/
static struct class *xxx_dev_class;
static struct class_device *xxx_dev_class_dev;

/*
xxx设备相关的相关操作函数:open、read、write、close、ioctl等
*/
static int xxx_dev_open(struct inode *inode, struct file *filp)
{
printk("Open xxx device OK.\n");
return 0;
}

static int xxx_dev_close(struct inode *inode, struct file *filp)
{
printk("Close xxx device OK.\n");
return 0;
}

static int xxx_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
printk("Write xxx device OK.\n");
return 0;
}

static int xxx_dev_read(struct file *file, const char __user *buf, size_t count, loff_t ppos)
{
printk("Read xxx device OK.\n");
return 0;
}

static int xxx_dev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
//struct xxx_dev *dev = filp->private_data;
printk("DRIVER : Get cmd %d.\n", cmd);
return 0;
}

/*
xxx设备操作函数结构体
*/
struct file_operations xxx_fops = {
.owner = THIS_MODULE,
.open = xxx_dev_open,
.release = xxx_dev_close,
.read = xxx_dev_read,
.write = xxx_dev_write,
.ioctl = xxx_dev_ioctl,
};

/*
xxx设备驱动模块的注册和卸载
*/
dev_t xxx_devno = 0;
int xxx_major = 0;
int xxx_minor = 0;
static int __init initialization_xxx_dev(void)
{
int ret = 0;

/* 申请设备号 */
printk("Before register xxx Major = %d\n", xxx_major);
if (xxx_major) {
/*指定主设备号*/
xxx_devno = MKDEV(xxx_major, xxx_minor);
ret = register_chrdev_region(xxx_devno, xxx_DEVICE_COUNT, "xxx");
} else {
/*系统自动分配主设备*/
ret = alloc_chrdev_region(&xxx_devno, xxx_minor, xxx_DEVICE_COUNT, "xxx");
xxx_major = MAJOR(xxx_devno);
xxx_minor = MINOR(xxx_devno);
}
if (ret < 0) {
printk("Can't get xxx Major %d\n", xxx_major);
return ret;
}
printk("After register xxx Major = %d\n", xxx_major);

/* 申请设备结构体内存 */
xxx_dev = kmalloc(sizeof(struct xxx_dev), GFP_KERNEL);
if (NULL == xxx_dev) {
printk("kmalloc failed.\n");
unregister_chrdev_region(xxx_devno, xxx_DEVICE_COUNT);
return -ENOMEM;
}

/* 字符设备注册 */
cdev_init(&xxx_dev->cdev, &xxx_fops);
xxx_dev->cdev.owner = THIS_MODULE;
xxx_dev->cdev.ops = &xxx_fops;
ret = cdev_add(&xxx_dev->cdev, xxx_devno, xxx_DEVICE_COUNT);
if (ret < 0)
{
printk("Cdev add failed.\n");
kfree(xxx_dev);
unregister_chrdev_region(xxx_devno, xxx_DEVICE_COUNT);
return ret;
}

/* 自动生成设备节点 */
xxx_dev_class = class_create(THIS_MODULE, "xxx_dev");
xxx_dev_class_dev = class_device_create(xxx_dev_class, NULL, xxx_devno, NULL, "xxx%d", xxx_minor);	// "/dev/xxx0"

/* 模块初始化成功必须返回0 */
printk("Module register OK.\n");
return 0;
}

static void __exit cleanup_xxx_dev(void)
{
/* 删除设备文件 */
cdev_del(&xxx_dev->cdev);
kfree(xxx_dev);
unregister_chrdev_region(xxx_devno, xxx_DEVICE_COUNT);
class_device_unregister(xxx_dev_class_dev);
class_destroy(xxx_dev_class);

printk("Module unregister OK.\n");
}

/*
模块注册与卸载
*/
module_init(initialization_xxx_dev);
module_exit(cleanup_xxx_dev);

/*
模块传参:insmod char_driver_frame.ko xxx_major=xxx xxx_minor=0
*/
module_param(xxx_major, int, S_IRUGO);
module_param(xxx_minor, int, S_IRUGO);

/*
模块的相关声明
*/
MODULE_AUTHOR("lhbo");
MODULE_DESCRIPTION("GPIO Driver for xxx");
MODULE_LICENSE("GPL");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: