1. 学习目标
- 理解什么是 Platform Device
理解嵌入式设备的特点:
设备直接挂在 SoC 上
没有传统总线
例如:
UART 控制器
GPIO 控制器
ADC
PWM
RTC
- 理解 Platform Driver 的作用
理解 Linux 如何管理这些设备
platform_device
platform_driver
- 理解驱动匹配机制
理解 Linux 如何匹配设备和驱动:
name match
device tree match
- 能编写基本 Platform Driver
掌握核心函数:
platform_driver_register
probe
remove
- 能从 Device Tree 获取硬件资源
掌握:
寄存器地址
IRQ
GPIO
2. 为什么需要 Platform Driver
PC 系统设备通常通过总线连接:
PCI
USB
SATA
设备可以自动枚举:
PCI Scan
但嵌入式系统不同。
设备通常是:
SoC 内部设备
例如:
UART controller
I2C controller
SPI controller
这些设备:
地址固定
不会自动发现
因此 Linux 需要一种机制描述它们:
platform device
3. Platform 驱动整体结构
Platform 设备模型:
Platform Bus
│
├── platform_device
│
└── platform_driver
匹配流程:
platform_device
│
│ match
▼
platform_driver
│
▼
probe()
4. Platform 设备结构
Platform 设备结构:
struct platform_device
{
const char *name;
int id;
struct device dev;
};
核心成员
name
用于匹配 driver
5. Platform Driver 结构
驱动结构:
struct platform_driver
{
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
struct device_driver driver;
};
核心函数:
probe
remove
6. Platform 驱动匹配机制
Linux 会匹配:
platform_device
platform_driver
匹配方式:
1 name match
device.name == driver.name
2 device tree match
使用:
compatible
例如:
compatible = "my-uart";
7. Platform Driver 生命周期
完整流程:
driver register
│
device register
│
driver match
│
probe()
│
device running
│
remove()
8. probe 函数
当设备匹配成功时:
probe()
被调用。
函数:
int probe(struct platform_device *pdev)
主要工作:
获取资源
初始化硬件
注册设备
9. remove 函数
驱动卸载时调用:
int remove(struct platform_device *pdev)
主要工作:
释放资源
关闭设备
10. Platform 资源(Resource)
设备资源包括:
寄存器地址
IRQ
DMA
Linux 使用:
struct resource
表示资源。
获取寄存器地址
platform_get_resource()
示例:
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
映射寄存器
ioremap()
示例:
base = devm_ioremap_resource(&pdev->dev,res);
获取中断
platform_get_irq()
示例:
irq = platform_get_irq(pdev,0);
11. Platform Driver 示例
简单 Platform 驱动:
static int my_probe(struct platform_device *pdev)
{
printk("platform driver probe\n");
return 0;
}
static int my_remove(struct platform_device *pdev)
{
printk("platform driver remove\n");
return 0;
}
static struct platform_driver my_driver =
{
.probe = my_probe,
.remove = my_remove,
.driver =
{
.name = "my_device",
},
};
module_platform_driver(my_driver);
12. Device Tree 与 Platform Driver
在嵌入式系统中:
设备通常来自 Device Tree
示例:
uart0: serial@10000000
{
compatible = "my-uart";
reg = <0x10000000 0x1000>;
interrupts = <5>;
};
驱动匹配:
static const struct of_device_id my_of_match[] =
{
{ .compatible = "my-uart" },
{ }
};
注册:
.driver = {
.name = "my_uart",
.of_match_table = my_of_match,
}
13. Platform Driver 完整流程
完整流程:
Device Tree
│
▼
platform_device
│
▼
platform bus
│
▼
platform_driver
│
▼
probe()
14. 驱动常见问题
probe没有调用
原因:
compatible 不匹配
resource获取失败
原因:
device tree错误
ioremap失败
原因:
地址错误
15. 总结
Platform 驱动核心结构:
Device Tree
│
platform_device
│
platform_bus
│
platform_driver
│
probe()
│
Driver
最重要原则:
设备描述 → Device Tree
驱动实现 → Platform Driver
16. Q&A
16.1 基础理解
-
为什么嵌入式 Linux 使用 platform driver?
-
platform device 和 platform driver 的关系?
16.2 匹配机制
-
compatible 的作用是什么?
-
probe 为什么会被调用?
16.3 资源管理
-
platform_get_resource 做什么?
-
为什么需要 ioremap?