裝置驅動程式經判定後,就會載入驅動程式代管程序程序 。決定載入與否的繫結程式 是驅動程式庫可繫結之裝置的說明。具有約束力的計畫 以小型網域特定語言定義,該語言已編譯為位元碼 會與驅動程式庫一起發行
Intel 乙太網路驅動程式的繫結程式範例:
fuchsia.device.protocol == fuchsia.pci.protocol.PCI_DEVICE;
fuchsia.pci.vendor == fuchsia.pci.vendor.INTEL;
accept fuchsia.pci.device {
0x100E, // Qemu
0x15A3, // Broadwell
0x1570, // Skylake
0x1533, // I210 standalone
0x15b7, // Skull Canyon NUC
0x15b8, // I219
0x15d8, // Kaby Lake NUC
}
繫結編譯器會採用繫結程式,並輸出 C 標頭檔案,
會定義巨集 ZIRCON_DRIVER
。ZIRCON_DRIVER
巨集包含
必要的編譯器指令,可將繫結程式放入 ELF NOTE
部分,方便裝置協調人員檢查
完全載入驅動程式庫程式。
ZIRCON_DRIVER
的第二個參數是 zx_driver_ops_t
結構指標
(由 lib/ddk/driver.h
定義,
會定義 init、繫結、create 和 release 方法。
驅動程式庫載入驅動程式主機程序時,系統會叫用 init()
,並允許
任何全域初始化作業。通常不需要。如果 init()
方法為
但驅動程式庫載入失敗
系統會叫用 bind()
,為驅動程式庫提供要繫結的裝置。裝置
符合驅動程式庫發布的繫結規則。如果 bind()
方法成功,
驅動程式庫「必須」建立新裝置,並將其新增為傳入的裝置子項
加入 bind()
方法。詳情請參閱裝置生命週期。
針對平台/系統匯流排驅動程式或 Proxy 驅動程式,系統會叫用 create()
。對於
大多數的驅動程式皆不需要使用這個方法。
系統會在驅動程式庫卸載前叫用 release()
,直到驅動程式的所有裝置都結束
在 bind()
及其他位置所建立的資源已遭刪除。目前這個方法:
never:駕駛座落於駕駛座的壽命後,會一直留在車上
上傳資料集之後,您可以運用 AutoML
自動完成部分資料準備工作
裝置生命週期
在驅動程式主機程序中,裝置會以 zx_device_t
結構的樹狀結構的形式存在,
是駕駛人看不見的畫面這些是從 device_add()
建立,也就是
驅動程式庫提供 zx_protocol_device_t
結構由
這個結構中的函式指標稱為「裝置作業」。
各種結構和函式都定義於 device.h
device_add()
函式會建立新的裝置,並將其新增為
提供的家長裝置。該上層裝置必須是通過測試的裝置
在裝置驅動程式庫程式的 bind()
方法中,或
由同一部裝置驅動程式庫建立
device_add()
的副作用是將新建立的裝置新增至裝置
提供給「裝置協調者」維護的全球裝置檔案系統。如果
裝置尚未實作 init()
掛鉤,表示裝置會立即生效
可在 devfs 中開啟節點
系統會在 device_add()
之後叫用 init()
掛鉤。這對於使用者
需要進行延伸初始化或探測,且不需要執行的驅動程式
開發人員明顯地發布裝置,直到成功發布為止 (並安靜地移除
如果失敗則建議通知)。駕駛應在呼叫 device_init_reply()
後呼叫
也已完成初始化這則回覆不一定要
該呼叫端透過 init()
掛鉤呼叫。裝置仍會隱藏,
保證在目前之前
不會移除
裝置僅供參考。可在驅動程式庫建立時取得參照
含有 device_add()
且遠端程序開啟裝置的裝置
透過裝置檔案系統
從呼叫 device_init_reply()
或呼叫 device_add()
的那一刻起
如未實作 init()
掛鉤,SDK 可能會呼叫其他裝置作業
驅動程式代管程序。
在裝置上呼叫 device_async_remove()
時,這麼做會安排移除作業
及其子系
移除裝置的程序包含四個部分:執行裝置的 unbind()
掛鉤、
從裝置檔案系統中移除裝置,並捨棄取得的參考資料
由 device_add()
執行,並正在執行裝置的 release()
掛鉤。
叫用 unbind()
方法時,這會向驅動程式庫發出信號,該方法應啟動
關閉裝置,並在取消繫結後呼叫 device_unbind_reply()
。
取消繫結也成為 FIDL 交易的硬性阻礙。
FDF 不允許任何新的 FIDL 交易或連線
會在呼叫 Unbind 時建立。駕駛負責
可用來結案或回覆尚未解決的交易
並在處理 FIDL 訊息時取消繫結。
此為選用提示。如未實作,系統會將其視為 device_unbind_reply()
都會立即呼叫呼叫 device_unbind_reply 時,
所有 FIDL 連線都會終止。
如果 unbind()
方法為
則可能是父項裝置 (已完成)
未繫結) 可以繼續接收裝置方法呼叫或通訊協定方法
呼叫。建議您在完成解除繫結前
上層裝置應安排這些方法傳回錯誤,
在兒童移除完成前來自孩童的來電。
工作或造成非預期的互動
只有在建立驅動程式庫完成後,才會呼叫 release()
方法
因此該裝置的所有已開啟執行個體都已關閉
且該裝置的所有子項都已解除繫結並釋出。這個
是驅動程式庫最後摧毀或釋出任何相關資源的最後機會
與使用者保持連線不適用於該裝置的「zx_device_t
」
release()
退貨後。針對以下項目呼叫任何裝置方法或通訊協定方法:
在此時間點後,從上層裝置取得的通訊協定屬於違法內容,且
可能會導致當機
卸除序列示例
為了說明 unbind()
和 release()
在拆除過程中的運作方式,
下方為 USB WLAN 驅動程式庫通常會如何處理。簡單來說
unbind()
呼叫序列為由上而下,release()
序列則是由下而上。
請注意,這只是一個範例,這可能與實際的 WLAN 驅動程式庫不一致 目前的狀態。
假設 WLAN 裝置已插入 USB 裝置,且具有 PHY 介面 透過 USB 裝置建立除了 PHY 介面外,2 個 MAC 介面之外 已在 PHY 介面下建立。
+------------+
| USB Device | .unbind()
+------------+ .release()
|
+------------+
| WLAN PHY | .unbind()
+------------+ .release()
| |
+------------+ +------------+
| WLAN MAC 0 | | WLAN MAC 1 | .unbind()
+------------+ +------------+ .release()
現在我們拔除這部 USB WLAN 裝置
USB XHCI 偵測到移除情形,並呼叫
device_async_remove(usb_device)
。這會導致系統呼叫 USB 裝置的
unbind()
。 取消繫結後,會呼叫device_unbind_reply()
。
usb_device_unbind(void* ctx) {
// Stop interrupt or anything to prevent incoming requests.
...
device_unbind_reply(usb_dev);
}
- 當 USB 裝置完成解除繫結時,系統會呼叫 WLAN PHY 的
unbind()
。 取消繫結後,會呼叫device_unbind_reply()
。
wlan_phy_unbind(void* ctx) {
// Stop interrupt or anything to prevent incoming requests.
...
device_unbind_reply(wlan_phy);
}
- 當 wlan_phy 完成取消繫結時,將會對其所有子項呼叫 unbind() (wlan_mac_0、wlan_mac_1)。
wlan_mac_unbind(void* ctx) {
// Stop accepting new requests, and notify clients that this device is offline (often just
// by returning a ZX_ERR_IO_NOT_PRESENT to any requests that happen after unbind).
...
device_unbind_reply(iface_mac_X);
}
移除裝置的所有用戶端,且該裝置沒有任何孩童後: 其 ref 將達到 0,系統會呼叫其 release() 方法。
系統會呼叫 WLAN MAC 0 和 1 的
release()
。
wlan_mac_release(void* ctx) {
// Release sources allocated at creation.
...
// Delete the object here.
...
}
- wlan_phy 沒有開放的連線,但仍有子裝置 (wlan_mac_0 和 wlan_mac_1)。 等到兩者都釋放後,其 Recount 最後就會變成零,並產生了 release() 方法。
wlan_phy_release(void* ctx) {
// Release sources allocated at creation.
...
// Delete the object here.
...
}
- 當 USB 裝置現在沒有任何子裝置或開啟連線時,系統就會呼叫其
release()
。