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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

platform_device与platform_driver

發布時間:2025/4/16 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 platform_device与platform_driver 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

做Linux方面也有三個多月了,對代碼中的有些結構一直不是很明白,比如platform_device與platform_driver一直分不清關系。在網上搜了下,做個總結。兩者的工作順序是先定義platform_device -> 注冊 platform_device->,再定義 platform_driver-> 注冊 platform_driver。

?(1)platform_device設備的注冊過程必須在相應設備驅動加載之前被調用,因為驅動注冊時需要匹配內核中所以已注冊的設備名。platform_device 是在系統啟動時在init.c 里的s3c_arch_init() 函數里進行注冊的。這個函數申明為arch_initcall(s3c_arch_init); 會在系統初始化階段被調用。arch_initcall 的優先級高于module_init,所以會在Platform 驅動注冊之前調用。現在內核中不是采用arch_initcall(s3c_arch_init) 注冊platform_device 結構體而是通過.init_machine成員將其保存在arch_initcall(customize_machine)等待調用(在mach-smdk6410.c中定義的MACHINE_START到MACHINE_END);其實質是一樣的均放在.initcall3.init等待調用。之后再定義結構體struct platform_driver,在驅動初始化函數中調用函數platform_driver_register() 注冊 platform_driver。詳細過程描述如下:

????? Linux從2.6版本開始引入了platform這個概念,在開發底層驅動程序時,首先要確認的就是設備的資源信息,在2.6內核中將每個設備的資源用結構platform_device來描述,該結構體定義在kernel/include/linux/platform_device.h中,

[cpp]?view plaincopy
  • struct?platform_device??
  • ??
  • {??
  • ??????const?char?*?name;??
  • ??????u32??id;??
  • ??????struct?device?dev;??
  • ??????u32??num_resources;??
  • ??????struct?resource?*?resource;??
  • };??

  • 該結構一個重要的元素是resource,該元素存入了最為重要的設備資源信息,定義在kernel/include/linux/ioport.h中,
    比如:

    [cpp]?view plaincopy
  • struct?resource???
  • ??
  • {??
  • ???????const?char?*name;??
  • ???????unsigned?long?start,?end;??
  • ???????unsigned?long?flags;??
  • ???????struct?resource?*parent,?*sibling,?*child;??
  • };??
  • 實例如:

    [cpp]?view plaincopy
  • static?struct?resource?s3c_usb_resource[]?=?{??
  • ?[0]?=?{??
  • ???????.start?=?S3C_PA_USBHOST,??
  • ???????.end???=?S3C_PA_USBHOST?+?S3C_SZ_USBHOST?-?1,??
  • ???????.flags?=?IORESOURCE_MEM,??
  • ?????},??
  • ?[1]?=?{??
  • ???????.start?=?IRQ_UHOST,??
  • ???????.end???=?IRQ_UHOST,??
  • ???????.flags?=?IORESOURCE_IRQ,??
  • ?????}??
  • };??

  • 以上是6410的USB? HOST分配的資源信息。第1組描述了這個usb host設備所占用的總線地址范圍,起始地址和大小由硬件決定,IORESOURCE_MEM表示第1組描述的是內存類型的資源信息;第2組描述了這個usb host設備的中斷號,也由硬件設定,IORESOURCE_IRQ表示第2組描述的是中斷資源信息。設備驅動會根據flags來獲取相應的資源信息。

    ????? 有了resource信息,就可以定義platform_device了:

    [cpp]?view plaincopy
  • struct?platform_device?s3c_device_usb?=?{??
  • ?????????.name????=?"s3c2410-ohci",??//s3c6410-usb??
  • ?????????.id????=?-1,??
  • ?????????.num_resources???=?ARRAY_SIZE(s3c_usb_resource),??
  • ?????????.resource???=?s3c_usb_resource,??
  • ?????????.dev??????????????=?{??
  • ?????????????????.dma_mask?=?&s3c_device_usb_dmamask,??
  • ?????????????????.coherent_dma_mask?=?0xffffffffUL??
  • ?????????????}??
  • };??

  • 有了platform_device就可以調用函數platform_add_devices向系統中添加該設備了。系統中的設備資源都可以采用這種方式列舉在一起,然后成一個指針數組,如:

    static struct platform_device *smdk6410_devices[] __initdata = {

    ......

    ?&s3c_device_usbgadget,
    ?&s3c_device_usb,??//jeff add.

    ......

    }

    然后在6410的初始化函數smdk6410_machine_init()中執行:

    platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));將所有的device添加進系統。platform_add_devices的好處在于它是一次性的執行多個platform_device_register。

    (2) 至于驅動程序需要實現結構體struct platform_driver,也定義在kernel/include/linux/platform_device.h中:

    [cpp]?view plaincopy
  • 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?(*suspend_late)(struct?platform_device?*,?pm_message_t?state);??
  • ??????int?(*resume_early)(struct?platform_device?*);??
  • ??????int?(*resume)(struct?platform_device?*);??
  • ??????struct?pm_ext_ops?*pm;??
  • ??????struct?device_driver?driver;??
  • };??

  • 則該處的USB HOST實現是:

    [cpp]?view plaincopy
  • static?struct?platform_driver?ohci_hcd_s3c2410_driver?=?{??
  • ?????.probe??=?ohci_hcd_s3c2410_drv_probe,??
  • ?????.remove??=?ohci_hcd_s3c2410_drv_remove,??
  • ?????.shutdown?=?usb_hcd_platform_shutdown,??
  • ?????/*.suspend?=?ohci_hcd_s3c2410_drv_suspend,?*/??
  • ?????/*.resume?=?ohci_hcd_s3c2410_drv_resume,?*/??
  • ?????.driver??=?{??
  • ??????????.owner?=?THIS_MODULE,??
  • ??????????.name?=?"s3c2410-ohci",??
  • ????????},??
  • };??

  • ????? 在驅動初始化(ohci-hcd.c的1124行)函數中調用函數platform_driver_register()注冊該platform_driver,需要注意的是s3c_device_usb結構中name元素和ohci_hcd_s3c2410_driver 結構中driver.name必須是相同的,這樣在platform_driver_register()注冊時會對所有已注冊的platform_device中元素的name和當前注冊的platform_driver的driver.name進行比較,只有找到具備相同名稱的platform_device存在后,platform_driver才能注冊成功。當注冊成功時會調用platform_driver結構元素probe函數指針,這里就是ohci_hcd_s3c2410_drv_probe開始探測加載。platform driver中的函數都是以platform device作為參數進入。

    (3)為什么兩個name的名字必須匹配才能實現device和driver的綁定?(1)在內核初始化時kernel_init()->do_basic_setup()->driver_init()->platform_bus_init()初始化platform_bus(虛擬總線);(2)設備注冊的時候platform_device_register()->platform_device_add()->(pdev->dev.bus = &platform_bus_type)把設備掛在虛擬的platform bus下;(3)驅動注冊的時候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev(),對每個掛在虛擬的platform bus的設備作__driver_attach()->driver_probe_device(),判斷drv->bus->match()是否存在并且是否執行成功,此時通過指針執行platform_match,比較strncmp(pdev->name, drv->name, BUS_ID_SIZE),如果相符就調用really_probe(實際就是執行的相應設備的platform_driver->probe(platform_device),注意platform_drv_probe的_dev參數是由bus_for_each_dev的next_device獲得)開始真正的探測加載,如果probe成功則綁定該設備到該驅動。

    ??????當進入probe函數后,需要獲取設備的資源信息,根據參數type所指定類型,例如IORESOURCE_MEM,來分別獲取指定的資源。
    struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);當然,也可以固定資源類型,如獲取資源中的中斷號:struct int platform_get_irq(struct platform_device *dev, unsigned int num);

    ????? probe函數一般完成硬件設備使能,struct resource的獲取以及虛擬地址的動態映射和具體類型設備的注冊(因為平臺設備只是一種虛擬的設備類型);remove函數完成硬件設備的關閉,struct resource以及虛擬地址的動態映射的釋放和具體類型設備的注銷。只要和內核本身運行依賴性不大的外圍設備 ( 換句話說只要不在內核運行所需的一個最小系統之內的設備 ), 相對獨立的擁有各自獨自的資源 (addresses and IRQs) ,都可以用platform_driver 實現。如:lcd,usb,uart 等,都可以用platfrom_driver 寫,而timer,irq等最小系統之內的設備則最好不用platfrom_driver 機制,實際上內核實現也是這樣的。


    ?參考原文:http://blog.chinaunix.net/u1/49507/showart_494193.html

    參考原文:http://blog.csdn.net/yd4330152763132/archive/2010/02/01/5275776.aspx

    總結

    以上是生活随笔為你收集整理的platform_device与platform_driver的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 好色先生视频污 | 香蕉久久网 | 2019中文字幕在线视频 | 窝窝午夜理论片影院 | 中文视频一区二区 | 中文字幕有码在线 | 麻豆传媒在线 | 欧美日韩国产综合在线 | 亚洲图片 欧美 | 99riav国产精品 | 草久久av| 日韩第三页 | 亚洲欧洲精品一区 | 日韩一级av毛片 | 日本一级黄色 | 鲁丝一区二区三区 | 久久久久国产精品 | 无码粉嫩虎白一线天在线观看 | 欧美激情一区在线 | 日不卡 | 久久精品无码一区二区三区免费 | www在线观看免费视频 | 秋霞欧美视频 | 欧美福利视频在线观看 | 夜夜艹天天干 | 欧美有码视频 | 69xx视频在线观看 | 亚洲AV无码乱码国产精品牛牛 | 久操不卡 | 中文在线字幕免费观看 | 久久久久亚洲av成人无码电影 | 久久精品中文闷骚内射 | 法国空姐电影在线 | 99啪啪| 男男上床视频 | 欧美a√在线 | 欧美一区二区三区久久成人精品 | 女人高潮潮呻吟喷水 | 岛国大片在线免费观看 | 黄色日批 | 一级欧美黄色片 | 国产福利电影在线 | 领导揉我胸亲奶揉下面 | a级片日本 | 在线免费观看不卡av | 欧美女优视频 | 丝袜人妻一区 | 在线免费看污视频 | 成人久久久 | 白嫩初高中害羞小美女 | 九九九精品视频 | 免费一级欧美片在线播放 | 国产99久 | 中国男女全黄大片 | 色欧美色| 伊人天堂av | 欧美videos另类精品 | 在线播放黄色av | 亚洲欧美综合色 | 日韩久久一区二区三区 | 性做久久久久久久 | 欧美三级a | 青草精品视频 | 韩国电影大尺度在线观看 | 精品国产免费人成在线观看 | 欧美 唯美 清纯 偷拍 | 久久综合加勒比 | 土耳其xxxx性hd极品 | 精品国产三级 | 国产91在线高潮白浆在线观看 | 丝袜+亚洲+另类+欧美+变态 | 午夜影音 | 日韩三级免费观看 | 欧美三级在线看 | 91重口味 | 丰满少妇一区二区三区视频 | 91在线精品秘密一区二区 | 成人av小说 | 日韩精品一二三四区 | 日本一区二区在线免费观看 | www.777含羞草 | 日韩av一卡二卡 | wwwww在线观看 | 亚洲jizzjizz | 久热久操| 欧美无遮挡 | 亚洲男女一区二区三区 | 在线视频网 | 玖玖zyz | 日本在线视频一区二区三区 | 老太脱裤让老头玩ⅹxxxx | 91官网在线观看 | 91色视频 | 高h喷水荡肉少妇爽多p视频 | 欧美大片在线 | 黄色午夜| 麻豆久久久久久久 | 日本免费在线视频观看 | 日本青青草 |