Linux设备驱动实现自己主动创建设备节点

时间:2023-03-08 17:41:47
Linux设备驱动实现自己主动创建设备节点
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/ioctl.h> #define DRIVERNAME "xxx"
#define DEV_MINOR 0
static dev_t xxx_devno = 0;
static struct class * xxx_class; struct xxx_dev
{
struct cdev cdev;
}xxxdev; /*-----------------------------------------------------------------------------------*/ static int xxx_open(struct inode *inode, struct file *filp)
{
return 0;
} static ssize_t xxx_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
} static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
return 0;
} static int xxx_release(struct inode *inode, struct file *filp)
{
return 0;
} static int xxx_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret = 0; switch (cmd)
{
case CPLD_VERSION:
break;
case CPLD_RESET:
break;
case CPLD_RELAY:
break;
case CPLD_RJ45:
break;
case CPLD_INTERUPT:
break;
case CPLD_FAN:
break;
default:
printk("Error xxx cmd\n");
break;
} return 0;
} /*-----------------------------------------------------------------------------------*/ static struct file_operations xxx_fops = {
.owner = THIS_MODULE,
.open = xxx_open,
.read = xxx_read,
.write = xxx_write,
.ioctl = xxx_ioctl,
.close = xxx_release,
}; static int xxx_init(void)
{
int ret = 0; /*动态申请设备号*/
ret = alloc_chrdev_region(&xxx_devno, DEV_MINOR, 1, DRIVERNAME);
if (ret < 0)
{
printk("xxx register char dev failed\n");
goto out;
}
/*初始化cdev结构,注冊cdev*/
cdev_init(&(xxxdev.cdev), &xxx_fops);
xxxdev.cdev.owner = THIS_MODULE;
ret = cdev_add(&(xxxdev.cdev), xxx_devno, 1);
if (ret)
{
printk("Error adding xxx device\n");
goto add_err;
} /*创建设备节点/sys/class/xxx和/dev/xxx*/
xxx_class = class_create(THIS_MODULE, DRIVERNAME);
if (IS_ERR(xxx_class))
{
ret = PTR_ERR(xxx_class);
goto class_err;
}
device_create(xxx_class, NULL, xxx_devno, NULL, DRIVERNAME); printk("xxx init\n");
return 0; class_err:
cdev_del(&(xxxdev.cdev));
add_err:
unregister_chrdev_region(xxx_devno, 1);
out:
return ret;
} static void xxx_exit(void)
{
device_destroy(xxx_class, xxx_devno);
class_destroy(xxx_class);
cdev_del(&(xxxdev.cdev));
unregister_chrdev_region(xxx_devno, 1);
printk("module xxx exit\n");
} module_init(xxx_init);
module_exit(xxx_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("liuwei");
MODULE_DESCRIPTION("char driver");