一、平台总线概念
1.1. 什么是平台总线
什么是平台总线
平台总线是Linux内核虚拟出来的一种总线,并不是实际存在的物理总线(I2C,SPI)。与物理总线的区别在于平台总线是虚拟的,抽象出来的。而物理总线(USB,PCI)是实际存在的硬件。
引入平台总线的目的
将驱动(driver)与硬件(device)资源进行分离,方便管理和统一与平台紧密相关的设备,并提供统一的接口进行访问。Linux中总线的分类
虚拟总线platform
和实际存在的物理总线I2C、SPI、USB
。平台总线的实现
平台总线的工作体系主要定义在driver/base/platform.c
中,主要涉及两个结构体struct platform_device
描述设备信息struct platform_driver
描述驱动程序,两者通过设备名字进行关联。优点
减少重复代码,提高程序可移植性及效率;
统一管理和控制各种硬件设备;
扩展性强,方便添加新的硬件设备;常见的平台总线
1.2. 平台总线的模型
概述:平台总线模型将设备驱动分为两部分:device.c
和driver.c
,分别用于描述硬件信息和控制硬件。通过字符串比较,具有相同name的设备(device.c)和驱动(driver.c)被匹配起来以控制硬件。
二、设备(device)&&驱动(driver)
2.1. 设备相关接口&&变量
2.1.1. 通用变量
struct platform_device
该结构体位于linux/platform_device.h
中
struct platform_device {
const char *name; /* 设备名称,用于与驱动进行关联 */
int id; /* 设备ID,-1:表示不设置 0~x:给设备标注序号 */
bool id_auto; /* 是否自动分配ID,1-自动分配;0-不分配 */
struct device dev; /* 描述设备的属性和状态,例如内存地址、中断号等 +重要+ */
u32 num_resources; /* 设备资源数量 */
struct resource *resource; /* 设备资源详细信息 +重要+ */
const struct platform_device_id *id_entry; /* 指向平台设备ID表的指针,用于匹配设备驱动程序[暂无需关注] */
char *driver_override; /* 强制匹配的驱动程序名称。如果该成员不为NULL,则表示强制匹配该名称的驱动程序[暂无需关注] */
struct mfd_cell *mfd_cell; /* 平台设备所属的MFD(多功能设备)单元[暂无需关注] */
struct pdev_archdata archdata; /* 平台设备的体系结构相关数据,用于存储与体系结构相关的信息[暂无需关注] */
};
struct device
该结构体位于linux/platform_device.h
中,当前只需要关注void (*release)(struct device *dev);
参数,且注册设备时,必须给该参数赋值,不然驱动无法正常编译。
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
const char *init_name; /* initial name of the device */
const struct device_type *type;
struct mutex mutex; /* mutex to synchronize calls to its driver. */
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this device */
void *platform_data; /* Platform specific data, device core doesn't touch it */
void *driver_data; /* Driver data, set and get with dev_set/get_drvdata */
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dm