在嵌入式Linux系統(tǒng)中,Platform設(shè)備驅(qū)動(dòng)是一種重要的驅(qū)動(dòng)模型,專門用于管理那些無法通過標(biāo)準(zhǔn)總線(如PCI、USB)探測(cè)到的設(shè)備。這類設(shè)備通常直接集成在處理器芯片內(nèi)部或通過固定地址連接到系統(tǒng)總線上,例如GPIO控制器、I2C適配器、定時(shí)器等片上外設(shè)。
Platform驅(qū)動(dòng)模型將設(shè)備與驅(qū)動(dòng)分離,通過“設(shè)備-總線-驅(qū)動(dòng)”的匹配機(jī)制實(shí)現(xiàn)動(dòng)態(tài)綁定,提高了代碼的可重用性和系統(tǒng)的可移植性。
platform_device)Platform設(shè)備代表一個(gè)具體的硬件實(shí)體,主要包含以下信息:
name):用于與驅(qū)動(dòng)匹配的關(guān)鍵標(biāo)識(shí)resource):設(shè)備的物理地址、中斷號(hào)等dev.platform_data):設(shè)備特定的私有數(shù)據(jù)platform_driver)Platform驅(qū)動(dòng)包含設(shè)備操作的具體實(shí)現(xiàn):
driver.name):必須與設(shè)備名稱匹配probe):設(shè)備被發(fā)現(xiàn)時(shí)調(diào)用的初始化函數(shù)remove):設(shè)備移除時(shí)的清理函數(shù)suspend/resume)id_table):支持多個(gè)設(shè)備匹配在板級(jí)支持包(BSP)或設(shè)備樹中定義Platform設(shè)備:
傳統(tǒng)方式(C代碼注冊(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);`
現(xiàn)代方式(設(shè)備樹描述):`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. 獲取設(shè)備資源
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. 獲取平臺(tái)數(shù)據(jù)
struct mydevconfig *config = devgetplatdata(&pdev->dev);
// 3. 從設(shè)備樹獲取參數(shù)(如果使用設(shè)備樹)
if (pdev->dev.ofnode) {
u32 value;
ofpropertyreadu32(pdev->dev.ofnode, "custom-param", &value);
}
// 4. 硬件初始化
// - 時(shí)鐘使能
// - 電源管理
// - 寄存器配置
// - 中斷注冊(cè)
// 5. 創(chuàng)建設(shè)備節(jié)點(diǎn)
// - 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)
{
// 恢復(fù)處理
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()宏簡化驅(qū)動(dòng)的注冊(cè)和注銷過程。
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. 查看已注冊(cè)的Platform設(shè)備`bash
# 查看/sys/bus/platform/devices/
ls /sys/bus/platform/devices/
cat /sys/bus/platform/devices/`
2. 查看驅(qū)動(dòng)匹配狀態(tài)`bash
# 查看/sys/bus/platform/drivers/
ls /sys/bus/platform/drivers/`
3. 動(dòng)態(tài)日志調(diào)試`c
// 在驅(qū)動(dòng)代碼中添加
prdebug("Probe called for device %s\n", pdev->name);
devdbg(&pdev->dev, "Mapped resource at %p\n", base);`
devm_系列函數(shù)自動(dòng)管理資源生命周期devm<em>ioremap</em>resource()替代ioremap()###
Platform設(shè)備驅(qū)動(dòng)是嵌入式Linux驅(qū)動(dòng)開發(fā)的核心內(nèi)容,特別是在i.MX8MM這類高度集成的SoC平臺(tái)上。通過合理使用Platform驅(qū)動(dòng)模型,結(jié)合設(shè)備樹的強(qiáng)大描述能力,可以開發(fā)出穩(wěn)定、可移植的外設(shè)驅(qū)動(dòng)。掌握Platform驅(qū)動(dòng)的開發(fā)流程和調(diào)試技巧,是嵌入式Linux開發(fā)者必備的核心技能。
在實(shí)際開發(fā)中,建議參考i.MX8MM官方Linux內(nèi)核源碼中的驅(qū)動(dòng)實(shí)現(xiàn),特別是drivers/目錄下的相關(guān)驅(qū)動(dòng)代碼,這些是學(xué)習(xí)和參考的最佳資料。
如若轉(zhuǎn)載,請(qǐng)注明出處:http://www.ylzbxs.cn/product/95.html
更新時(shí)間:2026-06-18 19:29:32
PRODUCT