Linux设备模型分析之(一):设备模型核心
Linux设备模型分析之(二):设备模型的基石
Linux设备模型分析之(三):sysfs
Linux设备模型分析之(四):class
Linux设备模型分析之(五):uevent
class,它主要是集合具有相似功能或属性的设备,这样就可以抽象出一套可以在多个设备之间共用的数据结构和接口函数。
设备驱动一般会调用class_create函数创建一个class,然后再class下创建设备,这样的话,就可以自动的创建设备文件了。
class结构体的定义如下:
struct class {
//class的名称,会在“/sys/class/”目录下体现
const char *name;
struct module *owner;
//该class的默认attribute,会在class注册到内核时,该class目录下创建对应的attribute文件
struct class_attribute *class_attrs;
/* 该class下每个设备的attribute,会在设备注册到内核时,自动在该设备的sysfs目录下创建对应
的attribute文件
*/
const struct attribute_group **dev_groups;
.....
//当该class下有设备状态(add、move)发生变化时,会调用class的uevent回调函数
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, umode_t *mode);
//用于release自身的回调函数
void (*class_release)(struct class *class);
......
struct subsys_private *p;
};
struct subsys_private {
struct kset subsys; //该class的kset
......
};
class_create函数执行流程如下:
创建class之后,就可以在这个class下创建设备:
来个示例,内核版本4.9.88。
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/init.h>
#include <linux/namei.h>
#include <linux/debugfs.h>
#include <linux/backing-dev.h>
#include <linux/blkdev.h>
#include <linux/swap.h>
struct class *my_class = NULL;
struct device *my_device = NULL;
dev_t dev;
static int my_class_init(void)
{
int retval;
//申请设备号
retval = alloc_chrdev_region(&dev, 0, 1, "vir_dev");
if(retval < 0)
{
printk(KERN_ALERT"alloc_chrdev_region failure!\n");
return retval;
}
//创建class,会在/sys/class目录下,创建一个my_class目录
my_class = class_create(THIS_MODULE, "my_class");
if(!my_class)
{
printk(KERN_ALERT"class_create failure!\n");
return -1;
}
//在my_class下创建my_dev设备
my_device = device_create(my_class, NULL, dev, "%s", "my_dev");
if(!my_device)
{
printk(KERN_ALERT"device_create failure!\n");
return -1;
}
return 0;
}
static void my_class_exit(void)
{
device_del(my_device);
class_destroy(my_class);
unregister_chrdev_region(dev, 1);
}
module_init(my_class_init);
module_exit(my_class_exit);
MODULE_LICENSE("GPL");
Makefile:
KERNELBUILD :=/lib/modules/$(shell uname -r)/build
default:
make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions *.mod
obj-m += my_class.o
编译安装驱动后,在/sys/class目录下:
my_class目录下有指向设备的软链接: