1. 程式人生 > >platform平臺匯流排工作原理詳解

platform平臺匯流排工作原理詳解

一、platform平臺匯流排的簡介
(1)相對於USB、PCI、I2C、SPI等物理匯流排來說,platform匯流排是一種虛擬、抽象出來的匯流排,實際中並不存在這樣的匯流排。
(2)cpu與外部通訊的兩種方式,地址匯流排式連結(32的cpu就有0-4G直接整合在cpu內部,以地址指標方式直接訪問,沒有具體的匯流排連結就用虛擬的platform平臺匯流排來控制內部的外設)和專用介面式(iic,pci,usb等這些外部匯流排連結的)連結平臺匯流排對應地址匯流排式連結裝置,也就是soc內部整合的各種內部外設

(3)思考:為什麼要有平臺匯流排?進一步思考:為什麼要有匯流排的概念?
因為大多數裝置都是整合在soc內部,和cpu直接連線,將其直接擴充套件到內部地址空間,因此他們本身就不該就有匯流排的概念,本身就不屬於匯流排的連結方式,但是如果一部分裝置設計得有匯流排,一部分沒匯流排就太亂了,所以除了iic,pci,spi等的裝置就歸類到平臺匯流排來便於管理

二、platform平臺匯流排下管理的2員大將
(1)platform工作體系都定義在drivers/base/platform.c中
(2)兩個結構體:platform_device和platform_driver
(3)兩個介面函式:platform_device_register和platform_driver_register

1、platform_device

struct platform_device {
    const char  * name;         // 平臺匯流排下裝置的名字
    int     id;
    struct device   dev;        // 所有裝置通用的屬性部分
u32 num_resources; // 裝置使用到的resource的個數 struct resource * resource; // 裝置使用到的資源陣列的首地址 const struct platform_device_id *id_entry; // 裝置ID表 /* arch specific additions */ struct pdev_archdata archdata; // 自留地,用來提供擴充套件性的 };

*對平臺匯流排下可利用的裝置資源結構體進行分析struct resource resource


struct resource { // 資源結構體
resource_size_t start; // 資源的起始值,如果是地址,那麼是實體地址,不是虛擬地址
resource_size_t end; // 資源的結束值,如果是地址,那麼是實體地址,不是虛擬地址
const char *name; // 資源名
unsigned long flags; // 資源的標示,用來識別不同的資源
struct resource *parent, *sibling, *child; // 資源指標,可以構成連結串列
};

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;  // 裝置ID表
};

三、平臺匯流排本身的初始化函式platform_bus_init

int __init platform_bus_init(void)
{
    int error;
    early_platform_cleanup();   //  進行一些早期的平臺清理  
    error = device_register(&platform_bus); //  註冊裝置 (在/sys/devices/目錄下建立 platform目錄對應的裝置物件  /sys/devices/platform/) 
    if (error)
        return error;
    error =  bus_register(&platform_bus_type);  //  匯流排註冊
    if (error)
        device_unregister(&platform_bus);
    return error;
}

四、platform平臺匯流排工作原理
1、平臺匯流排體系的工作流程
*(1)第一步:系統啟動時在bus系統中註冊platform
(2)第二步:核心移植的人負責提供platform_device
(3)第三步:寫驅動的人負責提供platform_driver
(4)第四步:platform的match函式發現driver和device匹配後,呼叫driver的probe函式來完成驅動的初始化和安裝,然後裝置就工作起來了*

2、程式碼分析:platform本身註冊
(1)每種匯流排(不光是platform,usb、i2c那些也是)都會帶一個match方法,match方法用來對匯流排下的device和driver進行匹配。理論上每種匯流排的匹配演算法是不同的,但是實際上一般都是看name的。
(2)platform_match函式就是平臺匯流排的匹配方法。該函式的工作方法是:如果有id_table就說明驅動可能支援多個裝置,所以這時候要去對比id_table中所有的name,只要找到一個相同的就匹配上了不再找了,如果找完id_table都還沒找到就說明每匹配上;如果沒有id_table或者每匹配上,那就直接對比device和driver的name,如果匹配上就匹配上了,如果還沒匹配上那就匹配失敗

3、以leds-s3c24xx.c為例來分析platform裝置和驅動的註冊過程
(1)platform_driver_register
(2)platform_device_register

platdata怎麼玩
(1)platdata其實就是設備註冊時提供的裝置有關的一些資料(譬如裝置對應的gpio、使用到的中斷號、裝置名稱····)
(2)這些資料在裝置和驅動match之後,會由裝置方轉給驅動方。驅動拿到這些資料後,通過這些資料得知裝置的具體資訊,然後來操作裝置。
(3)這樣做的好處是:驅動原始碼中不攜帶資料,只負責演算法(對硬體的操作方法)。現代驅動設計理念就是演算法和資料分離,這樣最大程度保持驅動的獨立性和適應性。