本指南介绍了如何在 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
)