关于从 DFv1 迁移到 DFv2 的常见问题解答

在开始从 DFv1 到 DFv2 的迁移之前 下面的问题可以帮助您确定特殊情况或极端情况 可能适用于您的司机的情况。

什么是兼容性填充码?何时有必要使用?

DFv1 和 DFv2 驱动程序存在于节点拓扑的单个分支下 (即直到所有驱动程序都迁移到 DFv2),并且需要 相互通信为帮助完成迁移过程 Fuchsia 的驱动程序框架团队创建了兼容性 shim, DFv1 驱动程序将融入 DFv2。

如果目标驱动程序与仍在使用的其他 DFv1 驱动程序进行通信 Banjo 和这些驱动程序不会一次性全部迁移到 DFv2, 您需要使用此兼容性填充码(方法是手动创建 compat::DeviceServer)用于在不同框架中启用驱动程序 相互通信

如需详细了解如何在 DFv2 驱动程序中使用兼容性填充码,请参阅 请参阅 在 DFv2 驱动程序中设置兼容型设备服务器 指南。

DFv2 驱动程序可以使用兼容性填充码与 Banjo 协议通信吗?

但我们强烈建议您将 DFv1 驱动程序从 Banjo 到 FIDL(如果 DFv2 驱动程序需要交谈) 一些现有的 Banjo 协议, 兼容性 shim 可提供 以下功能:

  • compat::BanjoServer让供应班卓琴变得更轻松 (请参阅 banjo_server.h)。
  • compat::ConnectBanjo,让您更轻松地连接到 Banjo (请参阅 banjo_client.h)。

有关这些功能的详情,请参阅 在 DFv2 驱动程序中提供 Banjo 协议 指南。

DFv2 驱动程序可以将兼容性填充码用于复合节点吗?

复合驱动程序的迁移过程几乎与 普通驱动程序,但复合驱动程序与 从父节点连接到 Banjo 或 FIDL 协议的方法。

由于复合节点有多个父级,因此复合驱动程序需要 以便在连接到家长账号时识别家长的姓名例如: 下方是一个正常的驱动程序, 父级:

zx::result client_result =
  compat::ConnectBanjo<ddk::HidDeviceProtocolClient>(incoming());

复合驱动程序的方法几乎完全相同,但父级方法除外 名称:

zx::result client_result =
  compat::ConnectBanjo<ddk::HidDeviceProtocolClient>(incoming(), "gpio-int")

新的 DFv2 驱动程序接口发生了哪些变化?

DFv2 的一个主要变化是驱动程序控制生命周期 由驱动程序创建的子nodes(或设备)列表。 这与 DFv1 不同,在 DFv1 中,驱动程序框架管理生命周期 例如拆卸设备, 整个设备树。

在 DFv1 中,设备由 zx_protocol_device 控制 而驾驶员由 zx_driver_ops 控制。 如果使用 ddktl,则需要 zx_protocol_device 中的接口 由 mixin 模板类中的 Ddk*() 函数封装。在 DFv2 中 这些接口发生了变化 显著增加。

在 DFv2 中,服务发现的工作原理是什么?

在 DFv2 中,必须使用 FIDL 服务来建立协议 连接。父驱动程序将 FIDL 服务添加到 fdf::OutgoingDirectory 对象并将其传送给子节点, 这样,家长的司机就可以向 子节点。

DFv1 和 DFv2 驱动程序在实现这一目标的方式上有所不同:

  • 在 DFv1 中,驾驶员在 DFv1 中设置并传递优惠, DeviceAddArgs::set_runtime_service_offers() 通话。然后,司机 创建 fdf::OutgoingDirectory 对象并将客户端传递给 结束句柄的 DeviceAddArgs::set_outgoing_dir() 调用。

  • 在 DFv2 中,驾驶员在 DFv2 中设置并传递优惠, NodeAddArgs::offers 对象。驱动程序将服务添加到 由 DriverBase 类封装的传出目录(最初为 由 Start() 函数提供)。当子驱动程序绑定到 子节点,驱动程序主机会传递传入的命名空间 包含 Service 传递给子驱动程序的 Start() 函数。

在子驱动程序端,DFv1 和 DFv2 驱动程序也会连接到 协议以不同方式提供服务:

  • DFv1 驱动程序调用 DdkConnectRuntimeProtocol<ServiceInstanceName>() 方法。
  • 如果存在以下情况,DFv2 驱动程序会调用 incoming()->Connect<ServiceInstanceName>(): 使用了 DriverBase 类。

    如需了解详情,请参阅 使用 DFv2 服务发现

驱动程序的节点(或设备)如何在 DFv2 系统中公开?

Fuchsia 拥有全局设备树,公开为称为 devfs:作为 /dev 路由到大多数组件。时间 当驱动程序添加设备节点时,可以选择添加 “文件”放入 devfs。然后,devfs 中的这个文件允许其他组件使用 以便与驾驶员对话。例如,音频驱动程序可能会将 扬声器设备节点,而音频驱动程序希望确保其他 组件可以使用此节点将音频输出到扬声器。要实现 因此,音频驱动程序会添加(或公开)devfs 节点 针对扬声器,使其显示为 /dev/class/audio/<random_number> 数据。

如需了解详情,请参阅在 DFv2 驱动程序中设置 devfs 指南。

在 DFv1 中提供的 DFv2 中并未实施哪项功能?

如果您的 DFv1 驱动程序调用 load_firmware() 函数 您需要实现自己的,因为等效的 函数在 DFv2 中不可用。不过,预计该流量将 易于实施

DFv2 的绑定规则发生了哪些变化?

DFv2 节点包含 其 FIDL 服务产品生成的节点属性

不过,在下列情况中,您不太可能需要修改绑定规则, 将现有 DFv1 驱动程序迁移到 DFv2。

DFv2 的登录流程发生了哪些变化?

DFv2 驱动程序无法使用 zxlogf() 函数或任何调试库 封装或使用此函数的代码。zxlogf()//src/lib/ddk/include/lib/ddk/debug.h,并且已从 DFv2 中的依赖项。向 DFv2 迁移的驱动程序需要 停止使用此库和其他库 依赖于它。

不过,我们新增了兼容性库,该库仅适用于 适用于 Fuchsia 源代码树 (fuchsia.git) 环境中, 现在添加了以允许 DFv2 驱动程序使用 DFv1 样式的日志记录。

DFv2 中的检查发生了哪些变化?

DFv1 驱动程序使用特定于驱动程序的检查函数来创建和更新 驱动程序维护的指标例如,在 DFv1 中 系统会调用 DeviceAddArgs::set_inspect_vmo() 函数来指明 驱动程序用于检查的 VMO。但在 DFv2 中 创建一个 inspect::ComponentInspector 对象。

在 DFv2 中,调度员会执行哪些操作?

FIDL 文件可为客户端和服务器生成模板和数据类型 配对。这些客户端和服务器端之间有一个通道, 两端的调度程序从通道中提取数据。有关 有关调度员的信息,请参见 驱动程序调度程序和线程

将 DFv1 驱动程序迁移到 DFv2 时,新的线程模型会出现哪些问题?

DFv2 中的 FIDL 调用不是在单线程基础上进行的,而是异步进行的 (但您可以通过添加 .sync() 使其同步 FIDL 调用或使用 fdf::WireSyncClient)。推动因素通常是 最好不要进行同步调用,因为它们可能会阻止 任务运行。(不过,如有必要,驱动程序可以创建 调度程序,FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS 只有 同步调度程序。)

鉴于 Banjo (DFv1) 和 FIDL (DFv2),则需要确定哪种类型的 FIDL 调用(即 同步或异步)。如果您的 原始代码围绕 Banjo 的同步性质而设计, 很难展开来将其全部异步化,那么您可能需要 不妨考虑先使用同步版本的 FIDL(它 但可能会导致目前的性能下降)。 之后,您可以重新审视这些调用,并将其优化为使用 同步调用。

DFv2 中的测试驱动程序发生了哪些变化?

驱动程序单元测试中使用的 mock_ddk 库 只限于 DFv1现已推出新的测试库 适用于 DFv2 驱动程序。

在进行迁移时,我是否应该将驱动程序克隆到 DFv2 版本?

针对迁移创建现有驱动程序的分支取决于其复杂性 信息。一般来说,建议避免为某个存储分区创建分支 因为这可能会增加工作量。不过, 对于大型驱动程序,将驱动程序转为 DFv2 版本,以便您逐步将迁移更改提交到 以更小的图块形式显示

您可以通过在 GN 参数中添加新的驱动程序组件来复刻驱动程序 并使用标志来决定是 DFv1 还是 DFv2 版本这个 示例 CL 演示了 DFv2 分支的原理 已添加 msd-arm-mali 驱动程序的 。

fuchsia.dev 上的 DFv2 概念文档和此 与上一个 DFv1 相比的 Gerrit 更改 Intel Wi-Fi 驱动程序迁移( pcie-iwlwifi-driver.cc 文件 包含大部分新 API)。