在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一文總結linux的platform驅動

嵌入式小生 ? 來源:嵌入式小生 ? 2023-10-16 16:45 ? 次閱讀

一、簡介

相關文件;

  • /include/linux/platform_device.h
  • /drivers/base/platform.c

在linux設備驅動中,有許多沒有特定總線的外設驅動,在實際開發中,又需要使用到總線、驅動和設備模型這三個概念,故而linux提供了platform這個虛擬總線,掛接在platform總線上的驅動稱為platform驅動,由struct platform_driver描述,掛接在platorm總線上的設備稱為platform設備,由struct platform_device描述。

在linux內核的驅動源碼中,可以看見很多基于platform驅動框架的驅動案例實現。

二、platform總線

在linux內核中,使用struct bus_type描述一個總線,為了抽象出platform這個虛擬總線,其定義如下(/drivers/base/platform.c):

structbus_typeplatform_bus_type={
.name="platform",
.dev_groups=platform_dev_groups,
.match=platform_match,
.uevent=platform_uevent,
.pm=&platform_dev_pm_ops,
};

platform總線的注冊由platform_bus_init()完成:

int__initplatform_bus_init(void)
{
interror;

early_platform_cleanup();

error=device_register(&platform_bus);
if(error)
returnerror;
error=bus_register(&platform_bus_type);
if(error)
device_unregister(&platform_bus);
of_platform_register_reconfig_notifier();
returnerror;
}

該函數在linux內核啟動過程中,在driver_init()中被調用,從而向linux內核注冊了platform總線。

7f22bd46-6bf9-11ee-939d-92fbcf53809c.png

三、platform設備和驅動的匹配過程

在定義platform總線的時候就定了該總線下設備和驅動的具體匹配過程,由platform_match()實現:

staticintplatform_match(structdevice*dev,structdevice_driver*drv)
{
structplatform_device*pdev=to_platform_device(dev);
structplatform_driver*pdrv=to_platform_driver(drv);

/*Whendriver_overrideisset,onlybindtothematchingdriver*/
if(pdev->driver_override)
return!strcmp(pdev->driver_override,drv->name);

/*AttemptanOFstylematchfirst*/
if(of_driver_match_device(dev,drv))
return1;

/*ThentryACPIstylematch*/
if(acpi_driver_match_device(dev,drv))
return1;

/*Thentrytomatchagainsttheidtable*/
if(pdrv->id_table)
returnplatform_match_id(pdrv->id_table,pdev)!=NULL;

/*fall-backtodrivernamematch*/
return(strcmp(pdev->name,drv->name)==0);
}

從上述代碼可知,platform設備和驅動的匹配分為了四種方式處理:

  • 1、基于設備樹的匹配方式。

struct device_driver結構中有個名為of_match_table的成員變量,此成員變量保存著驅動的compatible匹配表,在設備樹中的每個設備節點的compatible屬性會和of_match_table表中的所有成員比較,查看是否存在相同的條目,如果存在則表示設備和此驅動匹配,設備和驅動匹配成功以后probe函數就會執行(這個過程是由linux設備驅動模型中的總線去完成)。

  • 2、ACPI的匹配方式。

  • 3、id_table 匹配。

每個struct platform_driver有一個id_table成員變量,用于保存很多id信息,這些id信息存放著這個platform驅動所支持的驅動類型。

  • 4、比較name字段

如果第三種匹配方式的id_table不存在,就直接比較驅動和設備的name字段是否相等,如果相等則匹配成功;反之匹配不成功。

一般設備驅動為了兼容性都支持設備樹和無設備樹兩種匹配方式。也就是第一種匹配方式一般都會存在,第三種和第四種只要存在一種就可以,一般用的最多的還是第四種,也就是直接比較驅動和設備的name字段,因為這種方式最簡單了。

四、platrom驅動和platform設備

前文已經提到:掛接在platform總線上的驅動稱為platform驅動,由struct platform_driver描述,掛接在platorm總線上的設備稱為platform設備,由struct platform_device描述。要想開發基于platform設備驅動驅動框架的驅動程序,一定離不開這兩個數據結構。首先來看看platform驅動的描述者struct platform_driver,該結構定義如下(/include/linux/platform_device.h):

structplatform_driver{
int(*probe)(structplatform_device*);
int(*remove)(structplatform_device*);
void(*shutdown)(structplatform_device*);
int(*suspend)(structplatform_device*,pm_message_tstate);
int(*resume)(structplatform_device*);
structdevice_driverdriver;
conststructplatform_device_id*id_table;
boolprevent_deferred_probe;
};
  • probe:當驅動與設備匹配成功以后.probe函數就會執行,這是一個非常重要的函數,一般驅動的提供者都會設計該函數。
  • remove:當platform驅動移除的時候,.remove指向的函數將執行。
  • shutdown、suspend和resume:與電源管理相關的函數。
  • driver:為device_driver結構體變量,相當于C++中的基類,提供了最基礎的驅動框架。plaform_driver繼承了這個基類,然后在此基礎上又添加了一些特有的成員變量。
  • id_table:描述platform設備的id_table表,platform總線匹配驅動和設備的時候會使用。
  • prevent_deferred_probe:布爾類型變量(內部參數),用于防止驅動程序請求延遲probe,以避免進一步的徒勞的探測嘗試。

再看看platform設備的描述者struct platform_device,定義如下(/include/linux/platform_device.h):

structplatform_device{
constchar*name;
intid;
boolid_auto;
structdevicedev;
u32num_resources;
structresource*resource;

conststructplatform_device_id*id_entry;
char*driver_override;/*Drivernametoforceamatch*/

/*MFDcellpointer*/
structmfd_cell*mfd_cell;

/*archspecificadditions*/
structpdev_archdataarchdata;
};
  • name :name表示設備名字,該參數要和所使用的platform驅動的name字段相同,否則設備就無法匹配到對應的驅動。
  • id:設備id。
  • dev:linux內核面向對象的具體體現,用于描述platform_device的基類。
  • num_resources:表示資源的數量。
  • resource:表示資源,也就是設備的信息,比如外設寄存器等。Linux內核使用struct resource結構體表示資源。
  • id_entry:platform設備對應的id匹配表實例,在platform總線匹配驅動和設備的時候會使用到。

五、platform驅動設計

platform驅動設計的總體思路分為兩種:

  • (1)使用【struct platform_device + struct platform_driver】的方式實現。

在這種實現方式中,需要實現描述設備信息的struct platform_device結構,并需要使用platform_device來描述具體的設備信息,然后使用platform_device_register()函數將設備信息注冊到 Linux 內核中;如果不再使用platform了,可以通過platform_device_unregister()函數注銷相應的platform設備。

這種方式在不支持設備樹的linux內核中使用!

  • (2)使用【struct platform_driver + 設備樹】的方式來實現。

在編寫 platform 驅動的時候,首先定義一個struct platform_driver結構體變量,然后實現結構體中的各個成員變量,重點是實現匹配方法以及probe 函數。當驅動和設備匹配成功以后.probe函數就會執行,具體的驅動程序在 probe 函數里面編寫。當定義并初始化好 platform_driver 結構體變量以后,需要在驅動入口函數里面調用platform_driver_register()函數向Linux內核注冊一個platform驅動。

注意,如果linux內核支持設備樹,就可以不需要再使用struct platform_device來描述設備,直接使用設備樹去描述設備的信息。當然,如果一定要用struct platform_device來描述設備信息也是可以的。基于新版的linux內核的platform驅動的開發,通常是通過設備樹來描述設備信息,我們只需要實現對應的platform驅動即可。

六、代碼示例

本小節基于【struct platform_driver + 設備樹】給出一個基本的platform驅動的設計結構。

首先使用設備樹描述設備的信息:

debug_device_node{
compatible="iriczhao_debug";
pinctrl-0=<&pinctrl_usdhc2_8bit>;
pinctrl-1=<&pinctrl_usdhc2_8bit_100mhz>;
pinctrl-2=<&pinctrl_usdhc2_8bit_200mhz>;
bus-width=<8>;
non-removable;
status="okay";
};

上述代碼描述了一個名為debug_device_node的設備節點,給出了compatible屬性值。

platform驅動設計:

#include
#include
#include
#include

#include

#include

#include

staticintplatform_demo_probe(structplatform_device*dev)
{printk("
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
");
printk("doplatform_demo_probe
");
printk("
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
");

return0;
}

staticintplatform_demo_remove(structplatform_device*dev)
{
printk("doplatform_demo_remove
");
return0;
}

staticconststructof_device_idplatform_demo_id[]={
{.compatible="iriczhao_debug"},
{/*Sentinel*/}
};

MODULE_DEVICE_TABLE(of,platform_demo_id);

staticstructplatform_driverplatform_demo_driver={
.probe=platform_demo_probe,
.remove=platform_demo_remove,
.driver={
.name="dd",
.of_match_table=platform_demo_id,
}
};


staticint__initplatform_demo_init(void)
{
printk("doplatform_demo_init
");

returnplatform_driver_register(&platform_demo_driver);
}

staticvoid__exitplatform_demo_exit(void)
{
printk("doplatform_demo_exit
");

platform_driver_unregister(&platform_demo_driver);
}

module_init(platform_demo_init);
module_exit(platform_demo_exit);

MODULE_AUTHOR("IRIC");
MODULE_LICENSE("GPL");

以模塊方式構建上述代碼,運行后結果如下:

7f3a1f72-6bf9-11ee-939d-92fbcf53809c.png

從上述結果可知:platform驅動和對應的設備匹配成功,且.probe指向的函數得以執行,當模塊退出時,platform驅動將被移除,這時候.remove指向的函數得以執行。結果符合程序預期效果!


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11414

    瀏覽量

    212248
  • 函數
    +關注

    關注

    3

    文章

    4363

    瀏覽量

    63778
  • platform
    +關注

    關注

    0

    文章

    19

    瀏覽量

    17519

原文標題:干貨 | 一文總結linux的platform驅動

文章出處:【微信號:嵌入式小生,微信公眾號:嵌入式小生】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Linuxplatform機制開發驅動流程是怎么樣的?

    Linux 2.6起引入了套新的驅動管理和注冊機制:platform_device和platform_driver。
    發表于 09-23 07:31

    「正點原子Linux連載」第五十四章 platform設備驅動實驗(

    ,在這個思路下誕生了我們將來最常打交道的platform設備驅動,也叫做平臺設備驅動。本章我們就來學習Linux下的
    發表于 03-21 10:01

    「正點原子Linux連載」第五十四章 platform設備驅動實驗(二)

    IMX6U-ALPHA開發板上的LED燈,因此實驗硬件原理圖參考8.3小節即可。54.4試驗程序編寫本實驗對應的例程路徑為:開發板光盤->2、Linux驅動例程->17_platform。本章實驗我們
    發表于 03-21 10:02

    「正點原子Linux連載」第五十五章設備樹下的platform驅動編寫

    1)實驗平臺:正點原子Linux開發板2)摘自《正點原子I.MX6U嵌入式Linux驅動開發指南》關注官方微信號公眾號,獲取更多資料:正點原子第五十五章設備樹下的platform
    發表于 03-21 10:03

    Linux驅動之基本理論常識總結

    0 引言前面Linux專題中關于Linux下系統編程總結了17篇博,主要是為了提高Linux下的C編程應用能力,熟悉
    發表于 07-01 10:38

    Linux之leds_platform教程

    Linux之leds_platform教程,很好的Linux自學資料,快來學習吧。
    發表于 04-15 17:59 ?9次下載

    LCD驅動總結

    介紹了基于LINUX的LCD驅動總結,很詳細。是我在實際項目中所做的。
    發表于 06-20 17:48 ?13次下載

    Linux ALSA聲卡驅動之八:ASoC架構中的Platform

    前面幾章內容已經說過,ASoC被分為Machine,Platform和Codec三大部件,Platform驅動的主要作用是完成音頻數據的管理,最終通過CPU的數字音頻接口(DAI)把音頻數據傳送給Codec進行處理,最終由Cod
    發表于 05-06 17:39 ?2121次閱讀
    <b class='flag-5'>Linux</b> ALSA聲卡<b class='flag-5'>驅動</b>之八:ASoC架構中的<b class='flag-5'>Platform</b>

    linux Platform設備驅動

    個現實的Linux設備和驅動通常都需要掛接在種總線上,對于本身依附于PCI、USB、I2C、SPI等的設備而言,這自然不是問題, 但是在嵌入式系統里面,SoC系統中集成的獨立
    發表于 05-10 14:18 ?2079次閱讀

    Linux設備驅動platform

    根據Linux設備模型可知,個現實的Linux設備和驅動通常都需要掛接在種總線上,對于本身依附于PCI、USB等的設備而言,這自然不是問
    發表于 05-13 11:43 ?1144次閱讀
    <b class='flag-5'>Linux</b>設備<b class='flag-5'>驅動</b>之<b class='flag-5'>platform</b>

    驅動之路之platform按鍵驅動

    Linux 2.6起引入了套新的驅動管理和注冊機制,platform_device和platform_driver,
    發表于 05-15 17:14 ?1102次閱讀
    <b class='flag-5'>驅動</b>之路之<b class='flag-5'>platform</b>按鍵<b class='flag-5'>驅動</b>

    Linux內核驅動platform機制是怎樣的

    Linux 2.6起引入了套新的驅動管理和注冊機制:platform_device和platform_driver。
    發表于 11-06 14:12 ?1738次閱讀
    <b class='flag-5'>Linux</b>內核<b class='flag-5'>驅動</b>的<b class='flag-5'>platform</b>機制是怎樣的

    Linux驅動中的platform總線詳解

    platform總線是學習linux驅動必須要掌握的個知識點。 、概念 嵌入式系統中有很多的物理總線:I2c、SPI、USB、uart、
    的頭像 發表于 02-26 14:02 ?4284次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>驅動</b>中的<b class='flag-5'>platform</b>總線詳解

    深入解析LinuxPlatform_device 及Platform_driver

    [導讀] 前文分析了Linux設備驅動驅動模型,本文來聊聊Platform_driver/Platform_device這個類。做嵌入式
    發表于 02-07 10:10 ?11次下載
    深入解析<b class='flag-5'>Linux</b>下 <b class='flag-5'>Platform</b>_device 及<b class='flag-5'>Platform</b>_driver

    Linux內核中現存的所有platform_device

    platform_device,證明其來源于 dtb。 note:/proc/device-tree 是鏈接文件, 指向 /sys/firmware/devicetree/base 以上是 Linux 原生的節點,可以供我們使用。如果你用的芯片是某個廠家,這個廠家客制
    的頭像 發表于 07-30 15:28 ?1186次閱讀
    主站蜘蛛池模板: 好紧好爽的午夜寂寞视频 | 羞涩妩媚玉腿呻吟嗯啊销魂迎合 | 黄 色 片 在 线 看 | 色激情五月 | 国产拍拍拍精品视频 | 久久天天综合 | 如果我们是季节韩剧在线观看 | 天天操夜夜添 | 一本大道高清在线视频 视频 | 免费人成在线观看网站 | 午夜神马影院 | 久草cm| 四虎影视免费看 | 亚洲综合在线一区 | 午夜手机福利 | 五月天婷婷在线播放 | 欧美视频亚洲色图 | 免费视频在线播放 | 午夜视频在线观看一区 | 性满足久久久久久久久 | 四虎在线播放免费永久视频 | 亚洲免费区 | 天天色天天射天天操 | 国内精品伊人久久大香线焦 | 免费 在线观看 视频 | 国产免费人成在线看视频 | 69一级毛片| 欧洲不卡一卡2卡三卡4卡网站 | 日本a级特黄三级三级三级 日本边添边爱边摸边做边爱 | 国产精品漂亮美女在线观看 | 欧美video free xxxxx | 午夜美女久久久久爽久久 | 97人摸人人澡人人人超一碰 | 91成人在线播放 | 男女激情做爰叫床声视频偷拍 | 手机看高清特黄a大片 | 国产亚洲精品久久久极品美女 | 俺去啦最新网址 | 亚洲最新| 精品一区 二区三区免费毛片 | 69国产成人精品午夜福中文 |