在嵌入式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 = ;
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.vv858.cn/product/95.html
更新時間:2026-04-10 08:49:32