日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Linux设备驱动-platform虚拟总线dya01

發(fā)布時(shí)間:2023/12/20 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux设备驱动-platform虚拟总线dya01 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

參考連接:https://www.cnblogs.com/deng-tao/p/6026373.html
參考書:<Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解>宋寶華
根據(jù)參考資料和同事討論總結(jié).

摘要: platform的原理及相關(guān)結(jié)構(gòu)體

1、什么是platform(平臺(tái))總線?

相對于USB、PCI、I2C、SPI等物理總線來說,platform總線是一種虛擬、抽象出來的總線,實(shí)際中并不存在這樣的總線。

那為什么需要platform總線呢?
其實(shí)是Linux設(shè)備驅(qū)動(dòng)模型為了保持設(shè)備驅(qū)動(dòng)的統(tǒng)一性而虛擬出來的總線。因?yàn)閷τ趗sb設(shè)備、i2c設(shè)備、pci設(shè)備、spi設(shè)備等等,他們與cpu的通信都是直接掛在相應(yīng)的總線下面與我們的cpu進(jìn)行數(shù)據(jù)交互的,但是在我們的嵌入式系統(tǒng)當(dāng)中,并不是所有的設(shè)備都能夠歸屬于這些常見的總線,在嵌入式系統(tǒng)里面,SoC系統(tǒng)中集成的獨(dú)立的外設(shè)控制器、掛接在SoC內(nèi)存空間的外設(shè)卻不依附與此類總線。所以Linux驅(qū)動(dòng)模型為了保持完整性,將這些設(shè)備掛在一條虛擬的總線上(platform總線),而不至于使得有些設(shè)備掛在總線上,另一些設(shè)備沒有掛在總線上。

platform總線相關(guān)代碼:driver\base\platform.c 文件

相關(guān)結(jié)構(gòu)體定義:include\linux\platform_device.h 文件中

2.通俗理解

Platform虛擬總線
總線兩邊分別掛接設(shè)備和驅(qū)動(dòng),設(shè)備和驅(qū)動(dòng)互相探測,一旦探測成功(基于設(shè)備樹風(fēng)格的匹配,基于ID表,基于設(shè)備名和驅(qū)動(dòng)名)就可以對設(shè)備進(jìn)行操作了.

設(shè)備驅(qū)動(dòng)的開發(fā),我們可以總結(jié)為以下順序:
定義platform_device
注冊platform_device
定義platform_driver
注冊platform_driver

單片機(jī)是直接拿寄存器控制硬件.
而嵌入式設(shè)備因?yàn)橛胁僮飨到y(tǒng),必須通過驅(qū)動(dòng)來控制硬件設(shè)備.

3.platform平臺(tái)總線工作原理
平臺(tái)總線體系的工作流程
(1)第一步:系統(tǒng)啟動(dòng)時(shí)在bus系統(tǒng)中注冊platform
(2)第二步:內(nèi)核移植的人負(fù)責(zé)提供platform_device
(3)第三步:寫驅(qū)動(dòng)的人負(fù)責(zé)提供platform_driver
(4)第四步:platform的match函數(shù)發(fā)現(xiàn)driver和device匹配后,調(diào)用driver的probe函數(shù)來完成驅(qū)動(dòng)的初始化和安裝,然后設(shè)備就工作起來了

4.platform總線管理下的2員大將

兩個(gè)結(jié)構(gòu)體platform_device和platform_driver

對于任何一種Linux設(shè)備驅(qū)動(dòng)模型下的總線都由兩個(gè)部分組成:
描述設(shè)備相關(guān)的結(jié)構(gòu)體和描述驅(qū)動(dòng)相關(guān)的結(jié)構(gòu)體

在platform總線下就是platform_device和platform_driver

(1)platform_device結(jié)構(gòu)體:(include\linux\platform_device.h)

struct platform_device { // platform總線設(shè)備const char * name; // 平臺(tái)設(shè)備的名字int id; // ID 是用來區(qū)分如果設(shè)備名字相同的時(shí)候(通過在后面添加一個(gè)數(shù)字來代表不同的設(shè)備,因?yàn)橛袝r(shí)候有這種需求)struct device dev; // 內(nèi)置的device結(jié)構(gòu)體u32 num_resources; // 資源結(jié)構(gòu)體數(shù)量struct resource * resource; // 指向一個(gè)資源結(jié)構(gòu)體數(shù)組const struct platform_device_id *id_entry; // 用來進(jìn)行與設(shè)備驅(qū)動(dòng)匹配用的id_table表/* arch specific additions */struct pdev_archdata archdata; // 自留地 添加自己的東西};

platform_device結(jié)構(gòu)體中的struct resource結(jié)構(gòu)體分析:

struct resource { // 資源結(jié)構(gòu)體resource_size_t start; // 資源的起始值,如果是地址,那么是物理地址,不是虛擬地址resource_size_t end; // 資源的結(jié)束值,如果是地址,那么是物理地址,不是虛擬地址const char *name; // 資源名unsigned long flags; // 資源的標(biāo)示,用來識(shí)別不同的資源struct resource *parent, *sibling, *child; // 資源指針,可以構(gòu)成鏈表};

(2)platform_driver結(jié)構(gòu)體

struct platform_driver(){ int (*probe) (struct platform_device *); int (*remove) (struct platform_device *); void (*shutdown) (struct platform_device *); int (*suspend) (struct platform_device *,pm_message_t state); int (*resume) (struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; bool prevent_deferred_probe; };

其中,device_driver結(jié)構(gòu)體定義如下:

struct device_driver {const char *name;struct bus_type *bus;struct module *owner;const char *mod_name; /*used for built-in modules*/bool suppress_bind_attrs; /*disables bind/unbind via sysfs*/const struct of_device_id *of_match_table;const struct acpi_device_id *acpi_match_table;int (*probe) (struct device *dev);int (*remove) (struct device *dev);void (*shutdown) (struct device *dev);int (*suspend) (struct device *dev,pm_message_t state);int (*resume) (struct device *dev);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p; };

與platform_driver地位對等的i2c_driver,spi_driver,usb_driver等都包含device_driver結(jié)構(gòu)體實(shí)例成員,他其實(shí)描述了xxx_driver(xxx是總線名)在驅(qū)動(dòng)意義上的一些共性.

在Linux4.0以后,內(nèi)核直接使用設(shè)備樹來管理設(shè)備信息.設(shè)備樹中包含寄存器地址,中斷號(hào)等信息,直接寫成一個(gè)文本文檔,bootloader會(huì)將"這棵樹"傳給內(nèi)核,內(nèi)核解析其中的內(nèi)容,進(jìn)而展開內(nèi)核中的platform_device,i2c_client,spi_device等設(shè)備. 驅(qū)動(dòng)程序直接從設(shè)備樹的name進(jìn)行匹配, 匹配到就可以通過platform_get_resource函數(shù)得到設(shè)備信息和寄存器信息等,進(jìn)而控制硬件設(shè)備.

總結(jié)

以上是生活随笔為你收集整理的Linux设备驱动-platform虚拟总线dya01的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。