【linux字符设备驱动,带设备节点创建】

 

#include <linux/module.h> // module_init module_exit
#include <linux/init.h> // __init __exit
#include <linux/cdev.h>
#include <linux/fs.h>


#define MYNAME "chardev_test_longyh"

 
 
//DEVICE ID
dev_t devid;
static struct class *cls;
static struct device *test_device;
 
static int chardev_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "chardev open\n");
return 0;
}
 
static ssize_t chardev_read(struct file *file, char __user *buf,
size_t size, loff_t *ppos)
{
return 0;
}
 
 
static const struct file_operations chardev_fops = {
 
.open = chardev_open,
.read = chardev_read,
};
 
static struct
{
struct cdev cdev;
}chardev;
 
static int __init mymodule_init(void)
{
printk(KERN_INFO "chrdev_init helloworld init\n");
cdev_init(&chardev.cdev,&chardev_fops);
 
alloc_chrdev_region(&devid,2,1,MYNAME);
printk(KERN_INFO "MAJOR Number is %d\n",MAJOR(devid));
printk(KERN_INFO "MINOR Number is %d\n",MINOR(devid));
cdev_add(&chardev.cdev,devid,1);

cls = class_create(THIS_MODULE, MYNAME);
    if(IS_ERR(cls))
    {
cdev_del(&chardev.cdev);
unregister_chrdev_region(devid,1);
        return -EBUSY;
    }

test_device = device_create(cls,NULL,devid,NULL,MYNAME);//mknod /dev/hello
    if(IS_ERR(test_device))
    {
        class_destroy(cls);
cdev_del(&chardev.cdev);
unregister_chrdev_region(devid,1);
        return -EBUSY;
    }   
 
return 0;
}
static void __exit mymodule_exit(void)
{
printk(KERN_INFO "chrdev_exit helloworld exit\n");
cdev_del(&chardev.cdev);
unregister_chrdev_region(devid,1);
 
}
 
 
module_init(mymodule_init);
module_exit(mymodule_exit);
 
// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL"); // 描述模块的许可证
MODULE_AUTHOR("longyh"); // 描述模块的作者
MODULE_DESCRIPTION("module test"); // 描述模块的介绍信息
MODULE_ALIAS("alias xxx"); // 描述模块的别名信息
 
 
posted @ 2022-01-09 19:27  alone153  阅读(78)  评论(0)    收藏  举报