先决条件
如果您不熟悉 Inspect,建议您阅读以下页面:
简介
司机可以使用 Inspect。不过,鉴于驱动程序不是组件,因此必须考虑一些特殊事项。
请参考以下系统拓扑图:

图表图例:
灰色:组件。
蓝色:显示 out/diagnostics 目录内容的组件命名空间。
紫色:out/diagnostics/* 检查文件的内容。
组件可以通过以下方式公开检查数据:
- VMO 文件:通常称为
root.inspect - 树服务:
fuchsia.inspect.Tree协议的服务文件
一个组件可以公开这些文件中的一个或多个。在上图中,组件 foo 和 echo 公开单个文件。不过,driver_manager 会公开多个文件,每个设备对应一个 VMO 文件。
这是因为每个设备都不是组件,因此 driver_manager 会自行聚合其检查 VMO 并发布它们。这是从组件和从驱动程序公开检查数据之间的主要区别,会对如何通过选择器查询数据产生影响。
如果您想查询 foo 和 echo 组件的数据,可以在特定选择器中表达这一意图。例如,core/foo:root/child1:prop1、core/echo:root/child1:prop1。即使属性和节点以相同的方式调用,您也可以通过其别名唯一标识每个属性和节点,从而以独特的方式查询每个属性和节点。
不过,对于驱动程序,建议所有设备都公开一个检查层次结构,其中根具有一个名为设备的子级,以便使用选择器查询其数据时获得更好的体验。所有其他属性和节点都是此子节点的子节点。
在上图中,您可以单独查询 bootstrap/driver_manager:root/device_a:failures 和 bootstrap/driver_manager:root/device_b:failures。如果 device_a 和 device_b 均未通过 root/{device name} 节点(所有属性都位于该节点中)公开其检查 VMO,您将无法区分两者,并且选择器 bootstrap/driver_manager:root:failures 会同时匹配两者。
包括驱动程序中的检查
以下步骤将引导您完成在驱动程序中添加 Inspect 的操作。如需查看包含 Inspect 的驱动程序的完整示例,请参阅以下示例测试驱动程序。
在 BUILD.gn 中将 zircon inspect 库添加到驱动程序依赖项:
deps = [ ... "//zircon/system/ulib/inspect", ],在驱动程序中添加此标头:
#include <lib/inspect/cpp/inspect.h>在设备类中创建 Inspector 实例:
class TestDevice { … private: inspect::Inspector inspect_; }使用此方法创建属性和子项以构建检查树:
TestDevice::TestDevice() { state_ = inspect_.GetRoot().CreateString("state","invalid"); // inspect is a tree; You can add children and structure your data. performance_ = inspect_.GetRoot().CreateChild("performance"); call_count_ = performance_.CreateUint("call_count",0); total_time_ = performance_.CreateUint("total_time(ms)",0); ... } TestDevice::SetState(State s) { call_count_.Add(1); ... case kActive: state_.Set("active"); }Inspect 目前支持多种属性类型,例如整数、字符串、数组、布尔值、双精度浮点数、直方图。
检查是 RAII,因此请务必保留对您将更新的属性的引用,否则这些属性将从检查 VMO 中移除。
class TestDevice { … private: inspect::Inspector inspect_; inspect::StringProperty state_; inspect::Node performance_; inspect::UintProperty call_count_; inspect::UintProperty total_time_; }您可以向
inspect::ValueList添加属性和节点,而不是持有对它们的引用。 这样会将属性和节点的生命周期与inspect::ValueList的生命周期相关联。请注意,为方便起见,inspect::Inspector恰好是一个 ValueList。inspect_.GetRoot().CreateString("name","test device",&inspect_); inspect_.GetRoot().CreateString("config_params",config,&inspect_);将检查 VMO 导出到驱动程序管理器。
zx_status Bind() { … DdkAdd(ddk::DeviceAddArgs("test").set_inspect_vmo(inspect_.DuplicateVmo())); }每台设备只能发布一个检查 VMO。
完成。现在,您可以查看驱动程序的检查数据。
- 设备检查文件托管在
class/<protocol>/xxx.inspect中 - 使用
iquery检查检查数据
fx iquery show bootstrap/driver_manager --file class/ethernet/000.inspect // To view all of driver_manager and driver host fx iquery show bootstrap/driver_manager- 设备检查文件托管在
运行
fx snapshot并检查inspect.json中是否存在检查数据。请注意,反馈组件不属于启动的一部分,因此仅使用启动 build 时,拍摄快照并不是很有用。在这些情况下,建议使用iquery,该命令可在 bootfs 中使用(在启动时,如果您在其他产品中工作,请参阅下文)。
在 bootfs 中包含 iquery
bringup 产品和所有 *_eng 产品已在 bootfs 中包含 iquery,因此如果您使用的是上述任一产品,则可以跳过此部分。
如果您正在开发其他产品,并且需要在 bootfs 中提供 iquery,请将以下内容添加到 fx set 中:
fx set core.x64 --args='product_bootfs_labels+=["//bundles:diagnostics-eng"]'