Linux中的platform是一套用于管理嵌入式系统中常见硬件设备的驱动框架,属于Linux设备驱动模型的一部分,主要用来处理那些没有挂载到实际物理总线上的外设,比如SoC内部的定时器、看门狗、GPIO控制器等设备。

platform框架的核心组成
platform框架主要包含三个核心部分,分别是platform总线、platform设备和platform驱动,三者通过内核的设备驱动模型实现关联和匹配。
1. platform总线
platform总线是一种虚拟的总线类型,内核中已经预先定义好了对应的总线结构体,不需要用户手动注册。它的作用是维护platform设备和platform驱动的链表,当新的设备或驱动注册时,会触发总线上的匹配函数,尝试将设备和驱动进行绑定。
2. platform设备
platform_device结构体用来描述一个platform类型的硬件设备,它包含了设备的名称、资源(比如寄存器地址、中断号等硬件相关信息)、私有数据等内容。设备注册时,内核会把硬件资源信息记录下来,后续驱动可以通过接口获取这些资源。
下面是一个简单的platform设备定义示例:
#include <linux/platform_device.h>
// 定义设备的资源,这里示例一个寄存器地址区间和一个中断号
static struct resource my_platform_res[] = {
[0] = {
.start = 0x12340000, // 寄存器起始地址
.end = 0x123400FF, // 寄存器结束地址
.flags = IORESOURCE_MEM, // 内存资源类型
},
[1] = {
.start = 12, // 中断号
.end = 12,
.flags = IORESOURCE_IRQ, // 中断资源类型
},
};
// 定义platform设备
static struct platform_device my_platform_dev = {
.name = "my_platform_dev", // 设备名称,用于和驱动匹配
.id = -1, // id为-1表示只有一个该类型设备
.resource = my_platform_res, // 关联设备资源
.num_resources = ARRAY_SIZE(my_platform_res), // 资源数量
};
// 注册platform设备的函数
static int __init my_dev_init(void)
{
return platform_device_register(&my_platform_dev);
}
module_init(my_dev_init);
// 注销platform设备的函数
static void __exit my_dev_exit(void)
{
platform_device_unregister(&my_platform_dev);
}
module_exit(my_dev_exit);
3. platform驱动
platform_driver结构体用来描述一个platform设备的驱动程序,它包含了驱动的probe函数、remove函数、以及和设备匹配的相关信息。当设备和驱动匹配成功后,内核会调用驱动的probe函数,在这个函数里完成硬件的初始化、资源申请等操作;当设备被移除时,会调用remove函数释放资源。
对应的platform驱动示例代码如下:
#include <linux/platform_device.h>
#include <linux/module.h>
// probe函数,设备和驱动匹配成功后执行
static int my_platform_probe(struct platform_device *pdev)
{
struct resource *res_mem;
struct resource *res_irq;
// 获取内存资源
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res_mem) {
printk("get mem resource failedn");
return -ENODEV;
}
// 获取中断资源
res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res_irq) {
printk("get irq resource failedn");
return -ENODEV;
}
printk("probe success, mem start: 0x%x, irq: %dn", res_mem->start, res_irq->start);
return 0;
}
// remove函数,设备移除时执行
static int my_platform_remove(struct platform_device *pdev)
{
printk("platform device removedn");
return 0;
}
// 定义platform驱动
static struct platform_driver my_platform_drv = {
.probe = my_platform_probe,
.remove = my_platform_remove,
.driver = {
.name = "my_platform_dev", // 驱动名称,和设备名称匹配
.owner = THIS_MODULE,
},
};
// 注册platform驱动
static int __init my_drv_init(void)
{
return platform_driver_register(&my_platform_drv);
}
module_init(my_drv_init);
// 注销platform驱动
static void __exit my_drv_exit(void)
{
platform_driver_unregister(&my_platform_drv);
}
module_exit(my_drv_exit);
MODULE_LICENSE("GPL");
platform设备和驱动的匹配规则
platform总线的匹配函数会按照以下优先级尝试匹配设备和驱动:
- 首先匹配设备的
of_node和驱动的of_match_table,这是设备树场景下最常用的匹配方式,通过设备树节点的兼容属性来匹配。 - 如果设备树匹配失败,会匹配设备的
name和驱动的id_table,id_table是驱动支持的设备名称列表。 - 最后匹配设备的
name和驱动的driver.name,也就是前面示例中使用的名称匹配方式。
platform框架的优势
使用platform框架管理设备驱动主要有几个明显的优势:
- 实现了硬件资源和驱动逻辑的解耦,设备部分只负责描述硬件资源,驱动部分只负责处理逻辑,修改硬件资源不需要改动驱动代码。
- 统一了无物理总线设备的管理方式,不需要为每种设备单独设计管理逻辑,降低了驱动开发的复杂度。
- 支持热插拔和设备的动态注册注销,符合Linux设备驱动模型的通用规范,方便和其他内核子系统对接。
常见使用场景
platform框架在嵌入式Linux开发中应用非常广泛,几乎所有SoC内部集成的、不依附于PCI、USB等实际总线的外设,都会使用platform框架来管理。比如常见的LED驱动、按键驱动、内部RTC驱动、PWM驱动等,都可以基于platform框架实现,既规范又便于维护。
platform_deviceplatform_driverplatform_bus设备驱动模型修改时间:2026-07-07 10:00:29