驅動注冊的probe函數_第1頁
驅動注冊的probe函數_第2頁
驅動注冊的probe函數_第3頁
驅動注冊的probe函數_第4頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、精選優質文檔-傾情為你奉上驅動注冊的probe函數probe函數在設備驅動注冊最后收尾工作,當設備的device 和其對應的driver 在總線上完成配對之后,系統就調用設備的probe函數完成驅動注冊最后工作。資源、調用函數以及其他相關工作。下面是probe被調用的一些程序流程。從driver_register看起:cpp 1. int driver_register(struct device_driver * drv)  2.   3.     klist_i

2、nit(&drv->klist_devices, klist_devices_get, klist_devices_put);  4.     init_completion(&drv->unloaded);  5.     return bus_add_driver(drv);  6.   klist_init與init_completion沒去管它,可能是2.6的這個設備模型

3、要做的一些工作。直覺告訴我要去bus_add_driver。bus_add_driver中:都是些Kobject 與 klist 、attr等。還是與設備模型有關的。但是其中有一句:driver_attach(drv);單聽名字就很像:cpp 1. void driver_attach(struct device_driver * drv)  2.   3.     bus_for_each_dev(drv->bus, NULL, drv,

4、 _driver_attach);  4.   這個熟悉,遍歷總線上的設備并設用_driver_attach。在_driver_attach中又主要是這樣:driver_probe_device(drv, dev);跑到driver_probe_device中去看看:有一段很重要:if (drv->bus->match && !drv->bus->match(dev, drv)goto Done;明顯,是調用的驅動的總線上的match函數。如果返回1,則可以繼續,否則就Done了。繼承執行的話:cpp&#

5、160;1. if (drv->probe)  2.     ret = drv->probe(dev);  3. if (ret)   4.     dev->driver = NULL;  5.     goto ProbeFailed;  6.   只要p

6、robe存在則調用之。至此就完成了probe的調用。這個過程鏈的關鍵還是在drv->bus->match ,因為其余的地方出錯的話就是注冊失敗,而只要注冊不失敗且match返回1,那么就鐵定會調用驅程的probe了。你可以注冊一個總線類型和總線,并在 match中總是返回 1, 會發現,只要struct device_driver中的bus類型正確時,probe函數總是被調用.有兩個重要的鏈表掛在bus上,一個是設備device鏈表,一個是驅動driver鏈表。每當我們向一根bus注冊一個驅動driver時,套路是這樣的:driver_register(struct device_

7、driver * drv) -> bus_add_driver() -> driver_attach() ->bus_for_each_dev(drv->bus, NULL, drv, _driver_attach);bus_for_each_dev遍歷該總線上所有的device,執行一次_driver_attach(),看能不能將驅動關聯(attach)到某個設備上去。_driver_attach()->driver_probe_device()->drv->bus->match(dev, drv), / 調用bus的match函數,看devi

8、ce和driver匹不匹配。如果匹配上,繼續執行really_probe()。->really_probe()->driver->probe()。(如果bus->probe非空,則調用bus->probe)而每當我們向一根bus添加一個硬件時時,套路是這樣的:device_add() device_add 中有很多操作kobject,注冊sysfs,形成硬件hiberarchy結構的代碼。如果您忘記了,先回頭去參考參考"我是sysfs"->bus_attach_device() -> device_attach() ->bus

9、_for_each_drv()bus_for_each_drv與bus_for_each_dev類似,遍歷該總線上所有的driver,執行一次_device_attach(),看能不能將設備關聯(attach)到某個已登記的驅動上去。_device_attach()->driver_probe_device() /后面與上面一樣總結一些,一句話,注冊一個某個bus的驅動就是先把驅動自己鏈入到bus驅動鏈表中去,在從bus的設備鏈表中一一尋找,看有沒有自己可以關聯上的設備。找到就probe,再把二者bind起來。反之,添加設備道理也是一樣的。論壇討論帖:1. 在看platform驅動是,發

10、現一個很低能的問題,static int _devinitdm9000_probe(struct platform_device *pdev) 中的struct platform_device *pdev是從那里來的device,跟蹤platform_driver_register(&dm9000_driver);一直沒有發現platform_device的出現,但是現在probe函數中突然出現了這個變量,那么這個變量是從和而來?2. platform驅動分為platform_driver和platform_device兩個結構體表示,前者表示平臺驅動,后者表示平臺設備,這個struc

11、t platform_device *pdev就是在平臺相關文件里注冊的。平臺下會定義一個platform_device,然后platform_device_register(&platform_device),所以你注冊的平臺驅動,當在platform_bus上探測到有個設備的時候,這個你之前在平臺文件里注冊的platform_device就會傳過來。3. "platform_bus上探測到有個設備的時候"此句怎么理解,是怎么探測到的呢?4. 驅動肯定是自己注冊了。至于設備的注冊,有些設備所使用的協議有枚舉過程,從這處過程中可以得到設備信息,進而生成相應設備結構體

12、,然后注冊在相應總線上。在總線上注冊設備時,會遍歷該總線上已注冊的驅動,用總線的match方法判斷是否有匹配的驅動,如果有,則調用驅動的probe函數;在總線上注冊驅動時,會遍歷該總線上已注冊的設備,用總線的match方法判斷是否有匹配的設備,如果有,則調用驅動的probe函數。即,不管是先注冊設備還是先注冊驅動,總線的match方法會作用于所有組合,如果匹配了,則調用驅動的probe方法,這樣就探測到了。platform_bus是虛擬的總線,沒有具體的協議。上面所講設備的結構體是在枚舉時動態生成的,設備的注冊也是在枚舉時觸發的,而platform_device的定義與注冊是在平臺初始化文件里

13、手動做的。后面的情況就是一樣的了。其它一些沒有類似枚舉之類過程的總線,如I2C,也是這種流程。5. 內核啟動的時候, platform_device 是優先于 platform_driver 注冊的。 比如 platform_device A , 是在arch/arm/mach-XXXX/mach-XXXX.c 文件里注冊的, 而這個文件的代碼是 優先于 platform_driver_register 執行的。所以在你platform_driver_register執行的時候, platform_device A已經被掛在platform_bus總線上了, 而platform_driver_

14、register()有個功能是到platform_bus上去挨個找尋,找尋掛在上面的platform_bus上的platform_device。找到了就執行probe()。6. 可不可以這樣,我沒有試過。但是因為驅動中有 開發者實現的 probe 函數。 如果先注冊驅動, 驅動就找不到設備, 從而不執行probe函數,而驅動中最重要的就是probe函數,硬件的初始化,寄存器的配置,時鐘的使能都在probe函數里完成。從這一點來說,驅動先于設備注冊,應該不可行。7. 你好,關于I2C驅動,目前有三個問題想請教下:       1,請問用i2c_add_dr

15、iver注冊I2C的client端的驅動的時候,這個client是怎么和哪個adapter attach的(在此之前,系統中注冊了四個bit-style的adapter)?注意,我的i2c_driver中,并沒有賦值attach_adapter,但是賦值了probe    2,注冊adapter是用的 i2c_add_adapter,跟了下這個函數,發現它call的是->i2c_register_adapter->                 

16、60;                 adap->dev.bus = &i2c_bus_type;                           adap->dev.type = &i2c_adapter_type;      

17、60;                    res = device_register(&adap->dev);          這里是注冊的是一個device,那么根據device-driver的模型,那adapter的driver是怎么被賦值的呢?   3,i2c_add_driver是向哪跟總線上注冊的,是i2c_bus_type嗎?i2c_regist

18、er_adapter又是向哪跟總線注冊的呢? 也是i2c_bus_type嗎?   謝謝8. i2c_driver并不是要跟adapter綁定,而是要和i2c_client綁定 。注冊一個i2c_driver時并不知道它支持的設備在哪條總線上。例如一個系統有兩個i2c控制器,每個控制器上有一個相同型號的EEPROM,它們只需一個i2c_driver。關鍵在于如何發現哪條總線上有i2c_driver所支持設備。老I2C框架里,由i2c_driver負責發現設備,每注冊一個adapter遍歷已注冊i2c_driver,每注冊一個i2c_driver遍歷已注冊的i2c_adapt

19、er,不讓他們錯過任何一次組合,讓i2c_driver在adapter上探測一下是否有它支持的設備,如果有,則生成一個i2c_client實例。當然由于i2c協議很弱,這種探測很不可靠。現在(尤其在SOC系統中)傾向于靜態定義這些信息:如果我知道哪條總線上有哪個設備,我就犯不著讓i2c_driver去找它們了。于是在平臺初始化函數里注冊i2c_board_info,這個結構體就是一個i2c_client模板。i2c_board_info里有個bus_num作為匹配的憑證,如果bus_num與i2c_adapter的bus_num相同,那就匹配上了。所有注冊的i2c_board_info會放在一個鏈表里,每注冊一個i2c_adapter就去掃描這個鏈表,如果匹配就生成i2c_client。在老框架,i2c_client肯定是在i2c_driver時調用attach_adapter時出現的;新框架里則可以在沒有i2c_driver的情況下根據靜態信息生成i2c_client。另外讓i2c_driver探測設備時,頂多能知道設備地址,而欲查詢設備其它屬性,i2c協議里沒有通用的方法。而i2c_board_info靜態了提供了這些屬性。 而對于舊框架,新框架一方面在接口上保持兼容,另一方面在功能上也有更新。新框架里通過bus_num來區別是掃描

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論