#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");