本指南將說明如何在 DFv2 驅動程式庫中設定 devfs
,讓系統中的其他 Fuchsia 元件能夠偵測到驅動程式庫的服務。本指南會使用DFv2 驅動程式範例逐步說明 devfs
的設定程序。
步驟如下:
1. 找出目標 FIDL 通訊協定
在 DFv2 驅動程式的原始碼中,為此 devfs
設定識別目標 FIDL 通訊協定 (可繼承自 fidl::Server<>
或 fidl::WireServer<>
),例如:
class RetrieverDriver final : public fdf::DriverBase,
public fidl::Server<fuchsia_examples_metadata::Retriever> {
...
// fuchsia.hardware.test/Child implementation.
void GetMetadata(GetMetadataCompleter::Sync& completer) override {
...
}
};
(來源:retriever-driver.cc
)
本指南的範例使用 fuchsia.examples.metadata.fidl
中定義的 Retriever
通訊協定。
2. 新增 ServerBindingGroup 物件
將 ServerBindingGroup
物件新增至驅動程式庫類別,以繫結 FIDL 通訊協定,例如:
class RetrieverDriver final : public fdf::DriverBase,
public fidl::Server<fuchsia_examples_metadata::Retriever> {
...
fidl::ServerBindingGroup<fuchsia_examples_metadata::Retriever> bindings_;
(來源:retriever-driver.cc
)
3. 建立回呼函式
建立回呼函式,當用戶端嘗試連線至驅動程式庫時,系統會叫用此函式。在這個回呼函式中,新增從 ServerBindingGroup<>
物件到 ServerEnd
物件的繫結,例如:
class RetrieverDriver final : public fdf::DriverBase,
public fidl::Server<fuchsia_examples_metadata::Retriever> {
...
void Serve(fidl::ServerEnd<fuchsia_examples_metadata::Retriever> request) {
bindings_.AddBinding(dispatcher(), std::move(request), this, fidl::kIgnoreBindingClosure);
}
(來源:retriever-driver.cc
)
4. 初始化 devfs 連接器
在 步驟 1 中傳遞目標 FIDL 通訊協定,並在 步驟 3 中建立回呼函式,藉此初始化 devfs
連接器物件,例如:
driver_devfs::Connector<fuchsia_examples_metadata::Retriever> devfs_connector_{
fit::bind_member<&RetrieverDriver::Serve>(this)};
(來源:retriever-driver.cc
)
5. 將 devfs 連接器繫結至調度器
將 devfs
連接器繫結至驅動程式庫調度器,例如:
zx::result connector = devfs_connector_.Bind(dispatcher());
if (connector.is_error()) {
FDF_SLOG(ERROR, "Failed to bind devfs connector.", KV("status", connector.status_string()));
return connector.status_value();
}
(來源:retriever-driver.cc
)
6. 將 devfs 連接器新增至子節點
新增子節點時,請從步驟 5將繫結的 devfs
連接器傳遞至節點的 NodeAddArgs
物件。如要這麼做,請建立 DevfsAddArgs
物件,該物件已在 fuchsia.driver.framework/topology.fidl
中定義,並將 connector
欄位設為 devfs
連接器,例如:
fuchsia_driver_framework::DevfsAddArgs devfs_args{
{.connector = std::move(connector.value())}
};
zx::result owned_child = AddOwnedChild("retriever", devfs_args);
if (owned_child.is_error()) {
FDF_SLOG(ERROR, "Failed to add owned child.", KV("status", owned_child.status_string()));
return owned_child.error_value();
}
(來源:retriever-driver.cc
)