先决条件
如果您不熟悉 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 的驱动程序的完整示例,请参阅以下测试驱动程序示例。
将 zircon 检查库添加到 BUILD.gn 中的驱动程序依赖项:
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"); }
检查目前支持各种属性类型,例如整数、字符串、数组、布尔值、双精度和直方图。
检查属于 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 时,截取快照不是很有用。对于这些情况,最好使用 bootfs 中提供的iquery
(如果您使用的是其他产品,请在启动中使用,请参阅下文)。
在 bootfs 中包含 iquery
bringup
产品和所有 *_eng
产品均已在 bootfs 中包含 iquery
,因此,如果您使用的是这些产品,则可以跳过此部分。
如果您使用的是其他一些产品,并且需要在 bootfs 中提供 iquery
,请将以下代码添加到 fx set
:
fx set core.x64 --args='product_bootfs_labels+=["//bundles:diagnostics-eng"]'