在开始从 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)。