Linux Platform 总线、设备与驱动原理详解

📄 Linux Platform 总线、设备与驱动原理详解

🔷 什么是 Platform 总线?

Platform 总线(platform_bus) 是 Linux 内核提供的一种虚拟总线,用于管理和组织与特定硬件平台相关的设备和驱动。

它充当了 平台设备(platform_device)平台驱动(platform_driver) 之间的桥梁,负责将两者进行匹配和绑定

🌟 核心原则:

先分离后搭档。
硬件资源写在 device.c,驱动逻辑写在 driver.c,两者通过相同的名字匹配。

💡 platform 的应用场景:

没有明确标准总线的片上资源(SoC 内部),比如 GPIO、时钟控制器、LED、按键等。


🔷 为什么要用 Platform 总线?

✅ 设备和驱动分离,逻辑更清晰
✅ 提高驱动代码的复用性
✅ 减少重复代码
✅ 提高代码的可移植性


🔷 Platform 总线的三个角色

部分结构体作用包含内容
🛠 硬件资源struct platform_device告诉内核:我有一个 XXX 设备在这里名字、物理地址、IRQ、设备树节点
⚙️ 驱动逻辑struct platform_driver告诉内核:我能控制名字叫 XXX 的设备驱动逻辑、probe/remove 等回调
🚌 虚拟总线platform_bus匹配 device 和 driver管理两者的绑定关系

📄 硬件资源注册(device.c)

🔷 注册 platform 设备

通过 platform_device_register() 向内核注册一个平台设备。

🔷 platform_device 结构体

定义在:include/linux/platform_device.h
用于描述平台设备的硬件资源。

struct platform_device {
    const char *name;                // 设备名字
    int id;                          // 设备ID
    struct resource *resource;      // 硬件资源数组
    unsigned int num_resources;     // 资源个数
    ...
};

🔷 资源描述(struct resource)

定义在:include/linux/ioport.h
用于描述硬件资源:内存、I/O、IRQ 等。

struct resource {
    resource_size_t start;          // 资源起始地址
    resource_size_t end;            // 资源结束地址
    const char *name;               // 资源名字
    unsigned long flags;            // 资源类型标志
};

常见 flags:

类型
内存资源IORESOURCE_MEM
I/O 资源IORESOURCE_IO
中断资源IORESOURCE_IRQ

📄 驱动逻辑注册(driver.c)

🔷 注册 platform 驱动

通过 platform_driver_register() 注册平台驱动。

🔷 platform_driver 结构体

定义在:include/linux/platform_device.h

struct platform_driver {
    int (*probe)(struct platform_device *pdev);     // 匹配成功后调用
    int (*remove)(struct platform_device *pdev);    // 驱动卸载时调用
    struct device_driver driver;                    // 名字、of_match_table
};

匹配条件:

  • 如果有设备树:根据 compatible 匹配。
  • 没有设备树:platform_device.name == platform_driver.driver.name

🔷 驱动卸载

通过:

platform_device_unregister();
platform_driver_unregister();

从内核注销设备或驱动。


🔷 probe 函数的编写

当设备和驱动匹配成功后,内核会调用驱动的 probe() 函数。

典型流程:

✅ 打印匹配成功
✅ 获取硬件资源
✅ ioremap 资源地址
✅ 初始化硬件寄存器
✅ 注册字符设备
✅ 创建设备节点 /dev/xxx


🔷 获取硬件资源的两种方式

方法 1️⃣:直接访问资源数组

pdev->resource[i]

不推荐,写死了顺序。

方法 2️⃣:推荐使用 platform_get_resource()

struct resource *platform_get_resource(
    struct platform_device *pdev,
    unsigned int type,
    unsigned int num);

返回值:找到的资源指针,失败返回 NULL。


📄 平台驱动 + 字符设备示意

步骤关键 API
驱动注册platform_driver_register()
设备注册platform_device_register()
获取资源platform_get_resource()
地址映射ioremap()
操作寄存器readl()/writel()
注册 cdevcdev_add()
创建设备节点device_create()

🔷 probe() 关键步骤总结

1️⃣ 匹配成功打印
2️⃣ 获取资源:platform_get_resource()
3️⃣ ioremap:将物理地址映射为内核虚拟地址
4️⃣ 初始化硬件(GPIO、寄存器、默认状态)
5️⃣ 注册字符设备、创建设备节点


📄 Platform 总线驱动框架总结

步骤描述
📝 1编写 platform_device 描述硬件资源
📝 2编写 platform_driver 实现驱动逻辑
📝 3注册 device 和 driver
📝 4内核扫描匹配
📝 5调用 probe() 初始化设备

📖 匹配优先级

✅ 设备树(compatible) > 设备/驱动名字匹配


📋 总结

平台设备负责告诉内核硬件资源在这里。
平台驱动负责告诉内核我能控制这些硬件。
✅ 两者通过名字(或设备树)匹配成功后,调用驱动的 probe() 初始化设备。
✅ 所有资源的管理都通过 Platform 总线完成,逻辑清晰、便于维护。


🚀 推荐阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值