#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");
linux字符设备驱动程序框架,布布扣,bubuko.com
时间: 2024-10-03 22:42:28