<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          platform總線

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


          關鍵詞: platform總線偽總

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();