在嵌入式Linux系统中,Platform设备驱动是一种重要的驱动模型,专门用于管理那些无法通过标准总线(如PCI、USB)探测到的设备。这类设备通常直接集成在处理器芯片内部或通过固定地址连接到系统总线上,例如GPIO控制器、I2C适配器、定时器等片上外设。
Platform驱动模型将设备与驱动分离,通过“设备-总线-驱动”的匹配机制实现动态绑定,提高了代码的可重用性和系统的可移植性。
platform_device)Platform设备代表一个具体的硬件实体,主要包含以下信息:
name):用于与驱动匹配的关键标识resource):设备的物理地址、中断号等dev.platform_data):设备特定的私有数据platform_driver)Platform驱动包含设备操作的具体实现:
driver.name):必须与设备名称匹配probe):设备被发现时调用的初始化函数remove):设备移除时的清理函数suspend/resume)id_table):支持多个设备匹配在板级支持包(BSP)或设备树中定义Platform设备:
传统方式(C代码注册):`c
static struct resource mydevresources[] = {
[0] = {
.start = 0x020B4000,
.end = 0x020B4FFF,
.flags = IORESOURCEMEM,
},
[1] = {
.start = 88,
.end = 88,
.flags = IORESOURCE_IRQ,
},
};
static struct platformdevice mydevdevice = {
.name = "my-platform-device",
.id = -1,
.numresources = ARRAYSIZE(mydevresources),
.resource = mydevresources,
.dev = {
.platformdata = &mydevconfig,
},
};
platformdeviceregister(&mydev_device);`
现代方式(设备树描述):`dts
mydev: mydev@020B4000 {
compatible = "vendor,my-platform-device";
reg = <0x020B4000 0x1000>;
interrupts =
clocks = <&clk IMX8MMCLKMYDEV>;
clock-names = "ipg";
vdd-supply = <®_3v3>;
status = "okay";
};`
`c
#include #include
#include
#include
static int mydevprobe(struct platformdevice pdev)
{
struct resource res;
void _iomem *base;
int irq;
// 1. 获取设备资源
res = platformgetresource(pdev, IORESOURCEMEM, 0);
base = devmioremapresource(&pdev->dev, res);
if (ISERR(base))
return PTRERR(base);
irq = platformgetirq(pdev, 0);
if (irq < 0)
return irq;
// 2. 获取平台数据
struct mydevconfig *config = devgetplatdata(&pdev->dev);
// 3. 从设备树获取参数(如果使用设备树)
if (pdev->dev.ofnode) {
u32 value;
ofpropertyreadu32(pdev->dev.ofnode, "custom-param", &value);
}
// 4. 硬件初始化
// - 时钟使能
// - 电源管理
// - 寄存器配置
// - 中断注册
// 5. 创建设备节点
// - miscregister
// - cdevadd
// - device_create
return 0;
}
static int mydevremove(struct platformdevice *pdev)
{
// 资源释放
return 0;
}
#ifdef CONFIGPMSLEEP
static int mydev_suspend(struct device *dev)
{
// 挂起处理
return 0;
}
static int mydev_resume(struct device *dev)
{
// 恢复处理
return 0;
}
#endif
static SIMPLEDEVPMOPS(mydevpmops, mydevsuspend, mydev_resume);
static const struct ofdeviceid mydevofmatch[] = {
{ .compatible = "vendor,my-platform-device" },
{ },
};
MODULEDEVICETABLE(of, mydevofmatch);
static struct platformdriver mydevdriver = {
.probe = mydevprobe,
.remove = mydevremove,
.driver = {
.name = "my-platform-device",
.ofmatchtable = mydevofmatch,
.pm = &mydevpmops,
.owner = THIS_MODULE,
},
};
moduleplatformdriver(mydev_driver);
MODULELICENSE("GPL");
MODULEAUTHOR("Your Name");
MODULE_DESCRIPTION("Platform driver example for i.MX8MM");`
使用module<em>platform</em>driver()宏简化驱动的注册和注销过程。
struct clk *clk;
clk = devmclkget(&pdev->dev, "ipg");
if (!IS_ERR(clk)) {
clkprepareenable(clk);
}
`c
#include struct regulator *vdd;
vdd = devmregulatorget(&pdev->dev, "vdd");
if (!ISERR(vdd)) {
regulatorenable(vdd);
}`
`c
#include struct dmachan *dmach;
dmach = dmarequest_chan(&pdev->dev, "tx");`
1. 查看已注册的Platform设备`bash
# 查看/sys/bus/platform/devices/
ls /sys/bus/platform/devices/
cat /sys/bus/platform/devices/`
2. 查看驱动匹配状态`bash
# 查看/sys/bus/platform/drivers/
ls /sys/bus/platform/drivers/`
3. 动态日志调试`c
// 在驱动代码中添加
prdebug("Probe called for device %s\n", pdev->name);
devdbg(&pdev->dev, "Mapped resource at %p\n", base);`
devm_系列函数自动管理资源生命周期devm<em>ioremap</em>resource()替代ioremap()###
Platform设备驱动是嵌入式Linux驱动开发的核心内容,特别是在i.MX8MM这类高度集成的SoC平台上。通过合理使用Platform驱动模型,结合设备树的强大描述能力,可以开发出稳定、可移植的外设驱动。掌握Platform驱动的开发流程和调试技巧,是嵌入式Linux开发者必备的核心技能。
在实际开发中,建议参考i.MX8MM官方Linux内核源码中的驱动实现,特别是drivers/目录下的相关驱动代码,这些是学习和参考的最佳资料。
如若转载,请注明出处:http://www.scrd365.com/product/95.html
更新时间:2026-04-10 08:49:32