新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > platform總線

        platform總線

        作者: 時間:2016-12-14 來源:網絡 收藏
        platform總線實際上并不對應任何硬件上的總線,有時又稱為偽總線。由于設備模型中的驅動和設備關聯機制必須要有一條總線才能發揮作用,對于那些沒有連接在實際總線上的設備,如果想使用這種機制,就需要將它連接在一條假想的總線上。platform總線就可以起到這個作用,通常,platform總線上的設備都是直接與CPU相連的底層設備。
        使用platform總線的好處是可以將驅動與設備分離,驅動所需的平臺相關數據則在定義設備時提供,使驅動具有更大的跨平臺通用性。
        platform總線的相關定義和聲明在頭文件中。
        1.platform總線基本特征
        struct bus_type platform_bus_type = {
        .name = "platform",
        .match = platform_match,
        .uevent = platform_uevent,
        ......
        }
        匹配操作是platform_match,定義如下:
        static int platform_match(struct device *dev, struct device_driver *drv)
        {
        struct platform_device *pdev=to_platform_device(dev);
        struct platform_driver *pdrv=to_platform_driver(drv);
        if(pdrv->id_table)
        return platform_match_id(pdrv->id_table,pdev)!=NULL;
        return (strcmp(pdev->name,drv->name)==0);
        }
        其中調用的platform_match_id函數定義如下:
        static const struct platform_device_id *platform_match_id(
        struct platform_device_id *id, struct platform_device *pdev)
        {
        while(id->name[0]){
        if(strcmp(pdev->name, id->name) == 0){ pdev->id_entry=id; return id; }
        id++;
        }
        return NULL;
        }
        顯然在匹配時,先將設備的名稱與驅動的id_table成員數組中列舉的名稱逐一比較,若相同則匹配成功,否則再將設備的名字與驅動的名字比較,若相同則匹配成功。
        platform總線的用戶態事件鉤子函數是platform_uevent,定義如下:
        static int platform_uevent(struct device *dev, struct kobj_uevent_env *env){
        struct platform_device *pdev = to_platform_device(dev);
        add_uevent_var(env,"MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
        return 0;
        }
        也就是說,platform總線上的設備發送用戶態事件時,會增加一個MODALIAS環境變量。
        2.platform設備
        struct platform_device{
        const char *name;//設備名稱
        int id;//設備編號,-1表示只有一個
        struct device dev;//內嵌的設備對象
        u32 num_resources;//資源數組中的元素的個數
        struct resource *resource;//指向描述資源的數組
        struct platform_device_id *id_entry;//保存與驅動匹配后的ID
        }
        設備的名稱最終會被設為name.id,其中id是設備的編號。如果id的賦值為-1,表示設備的個數只可能是1個,這時設備的名字為name.
        num_resources和resource用于描述設備需要的全部資源,即端口號,IO內存、中斷號等,內存將它們統稱為資源。
        struct resource{
        resource_size_t start;//資源區域的起始值
        resource_size_t end;//資源區域的結束值
        const char *name;//申請資源的設備名稱
        unsigned long flags;//資源的標志
        struct resource *parent,*sibling,*child;//樹指針
        }
        每個struct resource類型的數據描述資源的一段區域,同一類型的所有資源以樹的形式組織在一起。資源的標志包含了資源類型的說明,常用類型如下:
        * IORESOURCE_IO :端口號資源
        * IORESOURCE_MEM :IO內存資源
        * IORESOURCE_IRQ :中斷號資源
        * IORESOURCE_DMA :DMA資源
        平臺相關的其他數據則放在platform設備的dev成員的platform_data指針所指向的內存中,。
        下面是platform設備的注冊和注銷函數的原型:
        int platform_device_register(struct platform_device *pdev);//注冊
        void platform_device_unregister(struct platform_device *pdev);//注銷
        注冊platform設備時,首先向platform總線注冊相應的設備,然后將設備的端口號和IO內存資源添加到系統的資源樹種,注銷platform設備則是相反的操作。
        通常一個系統中的platform設備的個數和類型總是固定的,因此可以把它們的地址放在一個數組中,然后用下面的接口函數同時注冊:
        int platform_add_devices(struct platform_device **devs, int num);
        3.platform驅動
        struct platform_driver{
        int (*probe)(struct platform_device *pdev)
        int (*remove)(struct platform_device *pdev);
        struct device_driver driver;//內嵌的驅動對象
        struct platform_device_id *id_table;//用于匹配的ID數組
        .......
        }
        在platform驅動的成員driver的各種操作函數中,實際上直接回調了platform驅動的各種操作,只是將參數的類型轉換了下。因為platform總線本身沒有probe和remove操作,所以當platform驅動注冊時,若platform總線上已經注冊了匹配的設備,就會調用驅動的probe方法。
        platform設備通常先于platform驅動而加載,這樣探測操作就會只發生在模塊的加載過程中,從而可以安全的放入初始化數據段,以節約內存。
        注冊和注銷platform驅動的接口函數如下:
        int platform_driver_register(struct platform_driver *drv);
        void platform_driver_unregister(struct platform_driver *drv);
        在platform驅動的probe函數中,可以用下面這個函數獲取設備的各種資源:
        struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned num);
        *dev指向要獲取資源的platform設備。
        *type資源的類型
        *num:資源的索引,表示要獲得設備的資源數組中第幾個此類型的資源,索引從0開始編號。
        獲取中斷號的接口函數:
        int platform_get_irq(struct platform_device *dev, unsigned int num);


        關鍵詞: platform總線偽總

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 渝中区| 柘城县| 海南省| 惠州市| 丰台区| 壤塘县| 东安县| 安陆市| 平顺县| 永城市| 丰台区| 扬州市| 汝南县| 电白县| 绥滨县| 新邵县| 四川省| 井研县| 礼泉县| 漾濞| 大关县| 天等县| 舟山市| 长岭县| 鄂托克前旗| 重庆市| 萍乡市| 滁州市| 湖州市| 肥西县| 饶河县| 平凉市| 金堂县| 镇江市| 白银市| 星子县| 雅安市| 唐海县| 海口市| 迁安市| 灯塔市|