這幾天搞ti的vpfe,裡面裝置的註冊使用platform,平台裝置註冊方式來註冊的。一直都知道
[cpp]view plain
copy
? 112 struct device_driver ;
裡的probe函式,但是不知道是何時被呼叫的。經過跟蹤**,在module_init(vpfe_init);模組初始化的時候,vpfe_init函式中呼叫了
[cpp]view plain
copy
? 4775 /* register driver to the kernel */
4776 err = driver_register(&vpfe_driver); 這裡
err = driver_register(&vpfe_driver);
的原型為:
[cpp]view plain
copy
? 171 int driver_register(struct device_driver * drv)
172
178 klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);
179 init_completion(&drv->unloaded);
180 return bus_add_driver(drv);
181 }
跟蹤bus_add_driver(drv);得到bus_add_driver(struct device_driver * drv)的原型:
[cpp]view plain
copy
? 479 int bus_add_driver(struct device_driver * drv)
480
491 drv->kobj.kset = &bus->drivers;
492 if ((error = kobject_register(&drv->kobj)))
496
497 driver_attach(drv);
498 klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
499 module_add_driver(drv->owner, drv);
500
501 driver_add_attrs(bus, drv);
502 add_bind_files(drv);
503 }
504 return error;
505 }
其中190 void driver_attach(struct device_driver * drv)
191
__driver_attach是乙個函式,原型:
155 static
int __driver_attach(struct device * dev, void * data)
156
這裡呼叫了 driver_probe_device(drv, dev);
原型:[cpp]view plain
copy
? 76 int driver_probe_device(struct device_driver * drv, struct device * dev)
77
92 } else
if (drv->probe)
98 }
99 device_bind_driver(dev);
100 ret = 1;
101 pr_debug("%s: bound device %s to driver %s/n",
102 drv->bus->name, dev->bus_id, drv->name);
103 goto done;
104
105 probefailed:
106 if (ret == -enodev || ret == -enxio) else
118 done:
119 return ret;
120 }
可以看出是先呼叫了匯流排的probe方法,接著呼叫了裝置的probe方法。
總之一句話,probe函式作為driver的最基本的函式指標,一旦你的device和driver匹配(match,由匯流排(bus)來完成,匹配工作發生在device_register()和drvier_register()
的時候),probe函式就肯定會被呼叫,期間一般會完成device的初始化,註冊中斷等操作。
順便講下在核心中是怎麼按照driver mode來實現整個系統的裝置和驅動註冊的。
在系統初始化階段,會首先向核心註冊各種常用的匯流排型別,比如pci, usb, spi, i2c, platform等等,當然你也可以自己發明一種匯流排型別註冊上去。
這部分**一般放在./arch/arm/mach-***/board-***.c中。
在此之後,會將系統的裝置列表,基本上整個系統的device都在這裡了,一一地註冊進核心,就是呼叫device_regisger註冊的過程。然後是對於各個device裝置driver的註冊。
這部分**一般放在./drvier/下面。
大部分device和driver的匹配方式就是看名字是否相同,這部分屬於匯流排分內的事情。
驅動呼叫過程
驅動呼叫過程 剛接觸到linux下驅動程式設計,一般都是照著模式寫 或是修改一下已有原始碼,對驅動的呼叫過程並不是很熟悉。在網上不斷的 算是有點明白了,現在我就說下自己的了解。我們載入驅動模組後都會做乙個工作,就是通過mknod在 dev資料夾下建立乙個裝置檔案 如mknod dev c major...
函式呼叫過程
每乙個未執行完的函式都對應著乙個棧幀,系統為單個函式分配的那部分棧空間就叫做棧幀,棧幀儲存了函式的資訊。以下面的 為例,通過彙編 的執行過程介紹棧幀建立和銷毀的過程 include int add int x,int y int main 從main函式建立自己的棧幀開始 其他內容先忽略 初始狀態 ...
cordova呼叫過程
cordova使前端js 可以呼叫到原生的objective c 本文小結一下具體的呼叫過程 var options datepicker.show options,function date 上面的datepicker就是cordova plugin設定的js物件,前端的js 可以像呼叫普通js函...