使用“检查驱动程序”

先决条件

如果您不熟悉检查功能,建议您先阅读 以下页面:

简介

驾驶员可以使用检查功能。不过,在执行此类操作时 因为驱动程序不是组件。

请参考以下系统拓扑图:

图 1:拓扑示例

图表图例:

灰色:组件。 蓝色:显示 out/diagnostics 目录内容的组件命名空间。 紫色out/diagnostics/* 检查文件的内容。

组件可以通过以下方式公开检查数据:

  • VMO 文件:通常称为 root.inspect
  • 树服务:适用于 fuchsia.inspect.Tree 协议的服务文件

一个组件可以公开一个或多个此类文件。在上图中,组件 fooecho 公开单个文件。不过,driver_manager 公开了多个文件,一个 VMO 文件 。

这是因为每个设备都不是组件,因此 driver_manager 会进行汇总 并自行发布要检查的 VMO这是公开检查 来自组件和驱动程序的数据,这些数据会影响查询数据的方式 过滤数据

如果您要查询 fooecho 组件的数据,可以使用 特定选择器。例如,core/foo:root/child1:prop1core/echo:root/child1:prop1。您 每个元素都有独特的查询方式,即使属性和节点的调用方式与给定参数相同, 您可以使用相应的名称对其进行唯一标识。

但是,对于驱动程序,建议所有设备都公开一个检查层次结构 其中根节点有一个包含设备名称的子项,以便使用 来查询其数据所有其他属性和节点均为此子项的子项。

在上图中,您可以查询 bootstrap/driver_manager:root/device_a:failuresbootstrap/driver_manager:root/device_b:failures 唯一。如果既不是 device_a,也不是 device_b 使用所有属性都所在的 root/{device name} 节点公开了其检查 VMO, 选择器和选择器 bootstrap/driver_manager:root:failures 与这两个查询都匹配。

在驱动程序中包含检查功能

以下步骤将指导您如何在驱动程序中添加 Inspect。如需查看驱动程序的完整示例, 如果包含检查,请参阅以下测试驱动程序示例

  1. 将 zircon 检查库添加到 BUILD.gn 中的驱动程序依赖项中:

    deps = [
        ...
        "//zircon/system/ulib/inspect",
    ],
    
  2. 在您的驱动程序中添加以下头文件:

    #include <lib/inspect/cpp/inspect.h>
    
  3. 在设备类中创建一个检查器实例:

    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_);
    
  4. 将检查 VMO 导出到驱动程序管理器。

    zx_status Bind() {
      …
        DdkAdd(ddk::DeviceAddArgs("test").set_inspect_vmo(inspect_.DuplicateVmo()));
    }
    

    您可以为每台设备发布一个检查 VMO。

  5. 完成。现在,您可以查看驱动程序的检查数据。

    • 设备检查文件托管在 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
    
  6. 运行 fx snapshot 并检查您的检查数据是否存在于 inspect.json 中。请注意, 反馈组件不是启动流程的一部分,因此在工作时截取快照不是很有用 只支持初期构建对于这些情况,请优先使用 bootfs 中提供的 iquery (如果您在开发其他产品,请参阅下文

在 bootfs 中包含 iquery

bringup 产品和所有 *_eng 产品均已在 bootfs 中包含 iquery,因此, 则可以跳过此部分

如果您正在开发其他产品,并且需要iquery bootfs,然后将以下内容添加到您的 fx set 中:

fx set core.x64 --args='product_bootfs_labels+=["//bundles:diagnostics-eng"]'