之前接触到的字符设备驱动是非常单纯的Linux字符设备驱动,他不具备工程中Linux驱动中的设备与驱动分离思想和设备驱动的分层思想,不具备“总线-设备-驱动”模型的概念。接下来通过分析platform设备驱动模型的搭建过程来看看Linux的设备驱动模型究竟是怎样的?
platform驱动模型搭建:(1)platform核心层:为设备层和驱动层提供注册接口、为设备层和驱动层的匹配提供标准
①搭建总线框架:总线类结构体:
struct bus_type {
const char *name;
struct bus_attribute *bus_attrs;
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs;
int (*match)(struct device *dev, struct device_driver *drv); //#####
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*suspend_late)(struct device *dev, pm_message_t state);
int (*resume_early)(struct device *dev);
int (*resume)(struct device *dev);
struct dev_pm_ops *pm;
struct bus_type_private *p; //看到这个private就有点C++类中的限定域关键字的意思,这个类的私有成员
};
总线类实例化:platform总线
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match, //关键成员
.uevent = platform_uevent,
.pm = PLATFORM_PM_OPS_PTR,
};
注册platform总线过程:
platform_bus_init()
{
.....
error = bus_register(&platform_bus_type);//注册platform总线的核心工作
.....
}
bus_register(struct bus_type *bus)
{
//创建bus的属性文件
retval = bus_create_file(bus, &bus_attr_uevent);
......
//在/sys/bus/bus->name目录下创建devices目录
priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);
....
//在/sys/bus/bus->name目录下创建drivers目录
priv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj);
//初始化总线设备\总线驱动链表
klist_init(&priv->klist_de