platform_driver 、 platform_device、device_driver 对这三种结果体详细说明,并说明三者之间的关系

在Linux内核设备驱动模型中,platform_driverplatform_devicedevice_driver是三个核心结构体,它们共同支持平台设备驱动模型的实现。以下是它们的详细说明及关系分析:


1. platform_device(平台设备)

  • 作用:表示集成在SoC(如ARM芯片)上的静态设备(无独立总线),例如内置的GPIO控制器、I2C控制器等。
  • 核心字段
    • name:设备名称(如"my-device"),用于与驱动匹配。
    • id:设备实例编号(如0表示第一个实例)。
    • devstruct device类型,包含设备资源(如IO内存、中断、DMA通道等)。
    • resource:指向设备资源的数组(通过platform_device_add_resources注册)。
  • 注册方式:通过platform_device_register()注册到内核,内核维护全局平台设备列表。

2. platform_driver(平台驱动)

  • 作用:为平台设备提供驱动实现,负责设备的初始化、资源分配和操作。
  • 核心字段
    • driverstruct device_driver类型,包含驱动名称、所有者(module)及通用操作(如proberemove)。
    • probe:设备匹配时调用的初始化函数(分配资源、注册子设备等)。
    • remove:设备卸载时调用的清理函数(释放资源)。
    • shutdownsuspendresume:电源管理相关回调。
  • 注册方式:通过platform_driver_register()注册,实际是将其driver字段注册到内核驱动模型。

3. device_driver(通用驱动结构)

  • 作用:内核设备驱动模型的核心抽象,代表一个通用的驱动。
  • 核心字段
    • name:驱动名称(如"my-driver"),用于与设备匹配。
    • bus:驱动所属的总线类型(如platform_bus_type)。
    • probe:设备匹配时调用的初始化函数(由具体驱动实现)。
    • remove:设备卸载时的清理函数。
    • owner:指向驱动模块的指针(用于引用计数)。
  • 特点device_driver是总线无关的通用驱动结构,platform_driver通过继承它实现平台设备驱动。

三者关系

  1. 继承关系
    • platform_driver内部包含一个struct device_driver成员(如driver字段),通过组合而非继承实现扩展。
    • 注册platform_driver时,内核会将其driver字段注册到全局驱动列表,并关联到platform_bus_type总线。
  2. 设备-驱动绑定
    • 匹配规则:当platform_devicenameplatform_driverdriver.name一致时,驱动与设备绑定。
    • 绑定流程
      1. 驱动注册时,内核遍历平台设备列表,匹配名称。
      2. 匹配成功后,调用驱动的probe函数,传递设备的struct device指针。
      3. probe函数通过platform_get_resource()等API获取设备资源,完成初始化。
  3. 资源管理
    • platform_device通过resource字段定义硬件资源(如IO地址、中断号)。
    • 驱动通过platform_get_resource()struct device中提取资源信息。

示意图

platform_driver
├── driver (struct device_driver)
│   ├── name: "my-driver"
│   ├── probe: my_probe()
│   └── remove: my_remove()
└── shutdown, suspend, resume...

platform_device
├── name: "my-device"
├── id: 0
├── resource: [IO_MEM, IRQ]
└── dev (struct device)

绑定关系:
platform_driver.driver.name == platform_device.name

总结

  • platform_device:描述静态硬件设备,提供资源信息。
  • platform_driver:实现设备驱动逻辑,通过继承device_driver注册到内核。
  • device_driver:通用驱动模型,platform_driver在其基础上扩展平台特定逻辑。
  • 核心机制:通过名称匹配实现驱动与设备的自动绑定,简化无总线设备的驱动开发。
<think>我们正在讨论Linux设备模型中的三个关键结构platform_deviceplatform_driverdevice_driver。 它们之间关系是: 1. platform_device 代表一个具的平台设备,通常描述SoC上的外设(如I2C控制器、SPI控制器等),它包含设备的资源(如内存地址、中断号等)。 2. device_driver 是一个通用的设备驱动结构,包含驱动的基本操作(如probe、remove)和设备模型需要的字段。 3. platform_driver 是平台设备驱动,它内嵌了一个device_driver结构扩展了平台设备特有的操作(如平台设备匹配和电源管理)。 具关系如下: - platform_driver 结构中包含一个 device_driver 结构成员(通常命名为driver)。 - platform_driver 通过其内部的 device_driver 成员与内核设备模型关联。 - 当注册一个 platform_driver 时,实际上是通过其内部的 device_driver 注册到总线上(platform_bus_type)。 - platform_deviceplatform_driver 通过名称进行匹配(即platform_device的name字段和platform_driver的id_table或者driver.name匹配)。 - 匹配成功后,会调用 platform_driver 中的 probe 函数。 结构定义(简化): ```c struct platform_device { const char *name; // 设备名称,用于匹配驱动 int id; struct device dev; // 内嵌的通用设备结构 // ... 资源信息等 }; struct device_driver { const char *name; // 驱动名称 struct bus_type *bus; // 所属总线 int (*probe)(struct device *dev); // 探测设备 int (*remove)(struct device *dev); // 移除设备 // ... 其他操作 }; struct platform_driver { int (*probe)(struct platform_device *); // 平台设备的探测函数 int (*remove)(struct platform_device *); // 移除函数 struct device_driver driver; // 内嵌的通用设备驱动 const struct platform_device_id *id_table; // 设备匹配表 }; ``` 工作流程: 1. 系统启动时,平台设备(platform_device)通常通过板级文件或设备树被注册到内核。 2. 驱动程序通过调用`platform_driver_register`注册一个platform_driver。 3. 内核的platform总线(platform_bus_type)会尝试将已注册的设备与驱动进行匹配。 4. 匹配依据:platform_driverdriver.name与platform_device的name匹配,或者platform_driver的id_table中的任一条目与platform_device的name匹配。 5. 匹配成功则调用platform_driver的probe函数(注意:实际调用的是platform_driver->driver.probe,但通常这个函数指针被设置为一个内部函数,该内部函数会调用platform_driver->probe,device转换为platform_device)。 注意:在platform_driver的初始化中,通常会将device_driver的probe函数设置为一个通用的平台驱动probe函数(例如platform_drv_probe),这个函数会调用platform_driver自己的probe函数。 总结: - platform_device 描述硬件设备。 - platform_driver 包含驱动该硬件设备的函数,内嵌一个device_driver。 - device_driver 是设备驱动的通用部分,由platform_driver中的driver成员实现。 关系图: platform_driver -> 包含 device_driver platform_device -> 包含 device 在总线上,device_driverdevice进行匹配,而实际上匹配的是platform_deviceplatform_driver。 §§相关问题§§ 1. 在内核中,platform_deviceplatform_driver是如何通过名称进行匹配的? 2. 当platform_driver注册时,其内嵌的device_driver的probe函数是如何被设置最终调用到platform_driver的probe函数的? 3. 设备树(Device Tree)机制下,platform_device是如何被创建和注册的? 4. platform_device结构中的struct device dev成员与device_driver结构有何关联? 5. 在platform驱动模型中,为什么需要将device_driver内嵌在platform_driver中,而不是直接使用device_driver?</think>### Linux设备驱动模型核心结构关系解析 #### 1. **基础层级关系** ```c struct device_driver { // 通用驱动抽象 const char *name; // 驱动名称 struct bus_type *bus; // 所属总线 int (*probe)(struct device *dev); // 探测设备 ... }; struct platform_driver { // 平台设备驱动 int (*probe)(struct platform_device *); struct device_driver driver; // 内嵌通用驱动结构 const struct platform_device_id *id_table; ... }; struct platform_device { // 平台设备实例 const char *name; // 设备名称 struct device dev; // 内嵌设备基类 struct resource *resource; // 设备资源 ... }; ``` #### 2. **关键交互机制** 1. **注册绑定流程** ```mermaid graph LR A[platform_device_register] --> B[注册到platform_bus] C[platform_driver_register] --> D[注册driverplatform_bus] B & D --> E[总线匹配driver.name与device.name] E --> F[调用platform_driver.probe] ``` 2. **结构内嵌关系** - `platform_driver` 包含 `device_driver` 成员 - `platform_device` 包含 `device` 成员 - 通过`container_of`宏实现父子结构转换: ```c struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct platform_driver *pdrv = container_of(drv, struct platform_driver, driver); ``` #### 3. **功能对比表** | 结构 | 作用域 | 关键成员 | 生命周期管理 | |------------------|-------------|----------------------------|-------------------| | `device_driver` | 通用驱动模型 | name, bus, probe | 所有设备类型通用 | | `platform_driver`| 平台设备驱动 | driver, probe, id_table | 封装platform特有操作 | | `platform_device`| 平台设备实例 | name, dev, resource | 描述SoC固定资源 | #### 4. **典型驱动开发流程** ```c // 定义平台驱动 static struct platform_driver my_driver = { .probe = my_probe, .driver = { .name = "my_device", // 匹配设备名称 .owner = THIS_MODULE, }, }; // 设备探测函数 static int my_probe(struct platform_device *pdev) { // 1. 获取设备资源 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); // 2. 映射寄存器 void __iomem *base = devm_ioremap_resource(&pdev->dev, res); // 3. 注册字符设备等操作 ... } // 注册驱动 module_platform_driver(my_driver); ``` #### 5. **设备树(Device Tree)整合** 现代Linux使用设备树替代硬编码`platform_device`: ```dts my_device: my_device@0x12340000 { compatible = "vendor,my-device"; // 匹配驱动 reg = <0x12340000 0x1000>; // 寄存器空间 interrupts = <0 45 4>; // 中断号 }; ``` 驱动通过`of_match_table`匹配: ```c static const struct of_device_id my_of_ids[] = { { .compatible = "vendor,my-device" }, {} }; struct platform_driver my_driver = { .driver = { .of_match_table = my_of_ids, }, }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值