网站开发语言总结,抄袭网站违法,百度 网站改版了,体育用品电子商务网站建设方案一. 简介 前面我们讲了设备驱动的分离#xff0c;并且引出了总线 (bus) 、驱动 (driver) 和设备 (device) 模型#xff0c;比如 I2C 、 SPI 、 USB 等总线。 但是#xff0c;在 SOC 中有些外设是没有总线这个概念的#xff0c;但是又要使用总 线、驱动和设备模型该怎么…一. 简介 前面我们讲了设备驱动的分离并且引出了总线 (bus) 、驱动 (driver) 和设备 (device) 模型比如 I2C 、 SPI 、 USB 等总线。 但是在 SOC 中有些外设是没有总线这个概念的但是又要使用总 线、驱动和设备模型该怎么办呢 为了解决此问题 Linux 提出了 platform 这个虚拟总线相应 的就有 platform_driver 和 platform_device 。 本文来学习 Linux内核中的 platform总线。 二. Linux下platform总线
1. platform总线的结构体 Linux 系统内核使用 bus_type 结构体表示总线此结构体定义在文件 include/linux/device.h bus_type 结构体内容如下 struct bus_type {const char *name;const char *dev_name;struct device *dev_root;struct device_attribute *dev_attrs; /* use dev_groups instead */const struct attribute_group **bus_groups;const struct attribute_group **dev_groups;const struct attribute_group **drv_groups;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 (*online)(struct device *dev);int (*offline)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;const struct iommu_ops *iommu_ops;struct subsys_private *p;struct lock_class_key lock_key;
};
第 10 行match 函数此函数就是完成设备和驱动之间匹配的。总线就是使用 match 函数来根据注册的设备来查找对应的驱动或者根据注册的驱动来查找相应的设备因此每一条总线都必须实现此函数。
match 函数有 两个参数dev 和 drv这两个参数分别为 device 和 device_driver 类型也就是设备和驱动。 platform 总线是 bus_type 的一个具体实例定义在文件 drivers/base/platform.c platform 总线定义如下 struct bus_type platform_bus_type {.name platform,.dev_groups platform_dev_groups,.match platform_match,.uevent platform_uevent,.pm platform_dev_pm_ops,
}; platform_bus_type 就是 platform 平台总线。 其中 platform_match 就是匹配函数。 2. 驱动与设备是如何匹配的 我们来看 一下驱动和设备是如何匹配的 platform_match 函数定义在文件 drivers/base/platform.c 中函 数内容如下所示 static int platform_match(struct device *dev, struct device_driver *drv)
{struct platform_device *pdev to_platform_device(dev);struct platform_driver *pdrv to_platform_driver(drv);/* When driver_override is set, only bind to the matching driver */if (pdev-driver_override)return !strcmp(pdev-driver_override, drv-name);/* Attempt an OF style match first */if (of_driver_match_device(dev, drv))return 1;/* Then try ACPI style match */if (acpi_driver_match_device(dev, drv))return 1;/* Then try to match against the id table */if (pdrv-id_table)return platform_match_id(pdrv-id_table, pdev) ! NULL;/* fall-back to driver name match */return (strcmp(pdev-name, drv-name) 0);
} 驱动和设备的匹配有四种方法我们依次来看一下 第 11~12 行第一种匹配方式 OF 类型的匹配也就是设备树采用的匹配方式 of_driver_match_device 函数定义在文件 include/linux/of_device.h 中。 device_driver 结构体 ( 表示 设备驱动 ) 中有个名为 of_match_table 的成员变量此成员变量保存着驱动的 compatible 匹配表 设备树中的每个设备节点的 compatible 属性会和 of_match_table 表中的所有成员比较查看是 否有相同的条目如果有的话就表示设备和此驱动匹配设备和驱动匹配成功以后 probe 函数 就会执行。 第 15~16 行第二种匹配方式 ACPI 匹配方式。 第 19~20 行第三种匹配方式 id_table 匹配每个 platform_driver 结构体有一个 id_table 成员变量顾名思义保存了很多 id 信息。这些 id 信息存放着这个 platform 驱动所支持的驱 动类型。 第 23 行第四种匹配方式如果第三种匹配方式的 id_table 不存在的话就直接比较驱动和 设备的 name 字段看看是不是相等如果相等的话就匹配成功。 对于支持设备树的 Linux 版本号一般设备驱动为了兼容性都支持设备树和无设备树两种匹配方式。 也就是第一种匹配方式一般都会存在第三种和第四种只要存在一种就可以一般用的最多的还是第四种也就是直接比较驱动和设备的 name 字段毕竟这种方式最简单了。