2. 字符串设备的创建

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>

// 主从设备号(高12位为主设备号,底20位为从设备号)~~~in include/linux/types.h
static dev_t s_dev;
// 设备类
static struct class *s_class;
// 自动创建最大设备数
static const uint32_t s_max_num = 10;

static int chr_open(struct inode *nd, struct file *filp)
{
    int _major;
    int _minor;

    _major = MAJOR(nd->i_rdev);
    _minor = MINOR(nd->i_rdev);

    printk("chr_open, major = %d, minor = %d\n", _major, _minor);
    return 0;
}

static ssize_t chr_read(struct file *filp, char __user *u, size_t sz, loff_t *off)
{
    printk("chr_read process!\n");
    return 0;
}

static ssize_t chr_write(struct file *filp, char __user *u, size_t sz, loff_t *off)
{
    printk("chr_write process!\n");
    return 0;
}

static int chr_close(struct inode *nd, struct file *filp)
{
    printk("chr_close process!\n");
    return 0;
}

// 记录文件系统调用函数指针~~~in include/linux/fs.h
static struct file_operations fopt = {
    .owner = THIS_MODULE,
    .open = chr_open,
    .read = chr_read,
    .write = chr_write,
    .release = chr_close,
};

// 模块加载
static __init int chr_device_init(void)
{
    // 注册字符设备,返回主设备号~~~in include/linux/fs.h
    int major = register_chrdev(0, "chr_device", &fopt);
    if(major < 0)
    {
        printk("char-device register fail\r\n");
        return -1;
    }
    s_dev = MKDEV(major, 0);

    // 创建设备类~~~in include/linux/device.h
    s_class = class_create(THIS_MODULE, "chr_device");
    if(NULL == s_class)
    {
        printk("class create fail\r\n");
        unregister_chrdev_region(s_dev, 255);
        return -1;
    }

    // 结合设备类以及设备号,开始自动创建设备(文件节点)~~~in include/linux/device.h
    uint32_t i = 0;
    for(i = 0; i < s_max_num; ++i)
    {
        if(NULL == device_create(s_class, NULL, s_dev+i, NULL, "chf_dev%d", i))
        {
            printk("device[%d] create fail\r\n", i);
            class_destroy(s_class);
            unregister_chrdev_region(s_dev, 255);
            s_class = NULL;
            return -1;
        }
    }

    printk("chr_device_init success\r\n");
    return 0;
}

// 模块卸载
static __exit void chr_device_exit(void)
{
    if(s_class) // 代表设备类有被创建
    {
        uint32_t i = 0;
        for(i = 0; i < s_max_num; ++i)
        {
            // 逐个销毁设备(文件节点)
            device_destroy(s_class, s_dev+i);
        }
        // 销毁设备类
        class_destroy(s_class);
        // 注销字符设备
        unregister_chrdev_region(s_dev, 255);
    }

    printk("chr_device_exit\r\n");
}

// 模块加载函数绑定~~~in include/linux/module.h
module_init(chr_device_init);
// 模块卸载函数绑定~~~in include/linux/module.h
module_exit(chr_device_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("chf");
MODULE_DESCRIPTION("This is just a chr_device module!\n");
上一篇:车间调度建模系列2|复杂车间调度问题描述


下一篇:linux 使用set_task 杀死D状态进程