日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux platform匹配机制,Linux驱动中的platform总线详解

發布時間:2025/4/16 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux platform匹配机制,Linux驱动中的platform总线详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

platform總線是學習linux驅動必須要掌握的一個知識點。

一、概念

嵌入式系統中有很多的物理總線:I2c、SPI、USB、uart、PCIE、APB、AHB

linux從2.6起就加入了一套新的驅動管理和注冊的機制platform平臺總線,是一條虛擬的總線,并不是一個物理的總線。

相比 PCI、USB,它主要用于描述SOC上的片上資源。platform 所描述的資源有一個共同點:在CPU 的總線上直接取址。

平臺設備會分到一個名稱(用在驅動綁定中)以及一系列諸如地址和中斷請求號(IRQ)之類的資源。

設備用platform_device表示,驅動用platform_driver進行注冊。

與傳統的bus/device/driver機制相比,platform由內核進行統一管理,在驅動中使用資源,提高了代碼的安全性和可移植性。

二、platform

1. platform總線兩個最重要的結構體

platform維護的所有的驅動都必須要用該結構體定義:

platform_driver

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;

};

該結構體,用于注冊驅動到platform總線,

成員含義

probe當驅動和硬件信息匹配成功之后,就會調用probe函數,驅動所有的資源的注冊和初始化全部放在probe函數中

remove硬件信息被移除了,或者驅動被卸載了,全部要釋放,釋放資源的操作就放在該函數中

struct device_driver driver內核維護的所有的驅動必須包含該成員,通常driver-》name用于和設備進行匹配

const struct platform_device_id *id_table往往一個驅動可能能同時支持多個硬件,這些硬件的名字都放在該結構體數組中

我們編寫驅動的時候往往需要填充以上幾個成員

platform_device

platform總線用于描述設備硬件信息的結構體,包括該硬件的所有資源(io,memory、中斷、DMA等等)。

struct platform_device {

const char *name;

int id;

bool id_auto;

struct device dev;

u32 num_resources;

struct resource *resource;

const struct platform_device_id *id_entry;

/* MFD cell pointer */

struct mfd_cell *mfd_cell;

/* arch specific additions */

struct pdev_archdata archdata;

};

成員含義

const char*name設備的名字,用于和驅動進行匹配的

struct devicedev內核中維護的所有的設備必須包含該成員,

u32num_resources資源個數

struct resource*resource描述資源

struct devicedev-》release()必須實現,

其中描述硬件信息的成員struct resource

0x139d0000

struct resource {

resource_size_t start; //表示資源的起始值,

resource_size_t end; //表示資源的最后一個字節的地址, 如果是中斷,end和satrt相同

const char *name; // 可不寫

unsigned long flags; //資源的類型

struct resource *parent, *sibling, *child;

};

flags的類型說明

#define IORESOURCE_MEM 0x00000200 //內存

#define IORESOURCE_IRQ 0x00000400 //中斷

內核管理的所有的驅動,都必須包含一個叫struct device_driver成員, //男性描述的硬件,必須包含struct device結構體成員。 //女性

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;

};

其中:

const char *name;

用于和硬件進行匹配。

內核描述硬件,必須包含struct device結構體成員:

struct device {

struct device *parent;

struct device_private *p;

struct kobject kobj;

const char *init_name; /* initial name of the device */

const struct device_type *type;

struct mutex mutex; /* mutex to synchronize calls to

* its driver.

*/

struct bus_type *bus; /* type of bus device is on */

struct device_driver *driver; /* which driver has allocated this

device */

void *platform_data; /* Platform specific data, device

core doesn‘t touch it */

struct dev_pm_info power;

struct dev_pm_domain *pm_domain;

#ifdef CONFIG_PINCTRL

struct dev_pin_info *pins;

#endif

#ifdef CONFIG_NUMA

int numa_node; /* NUMA node this device is close to */

#endif

u64 *dma_mask; /* dma mask (if dma’able device) */

u64 coherent_dma_mask;/* Like dma_mask, but for

alloc_coherent mappings as

not all hardware supports

64 bit addresses for consistent

allocations such descriptors. */

struct device_dma_parameters *dma_parms;

struct list_head dma_pools; /* dma pools (if dma‘ble) */

struct dma_coherent_mem *dma_mem; /* internal for coherent mem

override */

#ifdef CONFIG_DMA_CMA

struct cma *cma_area; /* contiguous memory area for dma

allocations */

#endif

/* arch specific additions */

struct dev_archdata archdata;

struct device_node *of_node; /* associated device tree node */

struct acpi_dev_node acpi_node; /* associated ACPI device node */

dev_t devt; /* dev_t, creates the sysfs “dev” */

u32 id; /* device instance */

spinlock_t devres_lock;

struct list_head devres_head;

struct klist_node knode_class;

struct class *class;

const struct attribute_group **groups; /* optional groups */

void (*release)(struct device *dev);

struct iommu_group *iommu_group;

bool offline_disabled:1;

bool offline:1;

};

其中:

void (*release)(struct device *dev);

不能為空。

2. 如何注冊

要用注冊一個platform驅動的步驟

1)注冊驅動platform_device_register

/**

* platform_device_register - add a platform-level device

* @pdev: platform device we’re adding

*/

int platform_device_register(struct platform_device *pdev)

{

device_initialize(&pdev-》dev);

arch_setup_pdev_archdata(pdev);

return platform_device_add(pdev);

}

2) 注冊設備platform_driver_register

#define platform_driver_register(drv)

__platform_driver_register(drv, THIS_MODULE)

三、舉例

1. 開發步驟

platform 總線下驅動的開發步驟是:

設備

需要實現的結構體是:platform_device 。

1)初始化 resource 結構變量

2)初始化 platform_device 結構變量

3)向系統注冊設備:platform_device_register。

以上三步,必須在設備驅動加載前完成,即執行platform_driver_register()之前,原因是驅動注冊時需要匹配內核中所有已注冊的設備名。

platform_driver_register()中添加device到內核最終還是調用的device_add函數。

Platform_device_add和device_add最主要的區別是多了一步insert_resource(p, r),即將platform資源(resource)添加進內核,由內核統一管理。

驅動

驅動注冊中,需要實現的結構體是:platform_driver 。

在驅動程序的初始化函數中,調用了platform_driver_register()注冊 platform_driver 。

總結

以上是生活随笔為你收集整理的linux platform匹配机制,Linux驱动中的platform总线详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。