本指南介绍了在 Fuchsia SDK 开发环境(使用 Bazel 构建系统)。
在 Fuchsia 驱动程序开发中,绑定库使以下任务 坐标:
Fuchsia SDK 包含一组绑定库,可用于编写绑定规则 。不过,有时仅使用现有的绑定库 足以为驱动程序编写精确的构建规则。在这种情况下 您可能需要创建新的绑定库来定义一组自定义的绑定 属性。
本指南中的开发场景
当新的绑定库可用时,两个具有两个不同 可能有兴趣使用新的绑定库: 用于管理父级驱动程序以及 子级驱动程序。
图 1.显示父子关系的节点拓扑 。
图 1 显示了具有两个驱动程序的节点拓扑:parent-driver
和
child-driver
。现在,假设一群平台开发者
为 Fuchsia 系统中的内置 ACPI 设备编写了驱动程序 (parent-driver
);
一组设备开发者正在为新的 Android 系统编写驱动程序 (child-driver
)
ACPI 设备,其目标节点为 bindlib-child
。
在这种情况下,会发生以下事件:
创建新的绑定库 - 创建一个新的绑定库 定义新 ACPI 设备的节点属性。
然后,这两个群组会共享这个新的自定义绑定库:
更新父驱动程序的子节点 - 管理“
parent-driver
”的开发者分配新的节点属性 子节点bindlib-child
。更新子驱动程序的绑定规则 - 负责开发
child-driver
的新 节点属性。
创建新的绑定库
创建一个新的绑定库,让开发者能够精确地标识 目标设备。
如需创建新的绑定库,请按以下步骤操作:
1. 编写新的绑定库
编写一个定义一组新的自定义节点属性的绑定库。
新的绑定库可能如下所示(请参阅 testlibrary.bind
)
在 bind 库示例的 lib
目录中:
library examples.gizmo.bind;
// Include properties from other libraries
using fuchsia.acpi;
// Define new properties and values for this library
string ModelName;
enum GizmoType {
MEM_64K,
MEM_128K,
MEM_256K,
};
// Extend values defined in other libraries
extend uint fuchsia.BIND_PCI_VID {
GIZMOTRONICS = 0x314159,
};
这个新绑定库的名称在代码行的顶部
library fuchsia.examples.gizmo.bind;
。另请注意,以下代码行
using fuchsia.acpi;
建立对 fuchsia.acpi
绑定的依赖关系
库(包含在 Fuchsia SDK 中)。此设置反映了现实开发
这通常需要使用两种类型的绑定库:一个现有的库,
和自定义库
2. 为新的绑定库创建 build 文件
为新的绑定库创建一个 build 文件(即 BUILD.bazel
),以便
开发者可以自动生成库工件
以下构建目标定义了一个名为
fuchsia.example.gizmo.bind
(在示例绑定库的
BUILD.bazel
文件:
# This is a bind library that we manually define.
fuchsia_bind_library(
name = "examples.gizmo.bind",
srcs = [
"testlibrary.bind",
],
visibility = ["//visibility:public"],
deps = [
"@fuchsia_sdk//bind/fuchsia.acpi", # An SDK bind library.
],
)
# We have to create the C++ library for it manually as well.
fuchsia_bind_cc_library(
name = "examples.gizmo.bind_cc",
library = ":examples.gizmo.bind",
visibility = ["//visibility:public"],
# Has to have the C++ libraries of all the deps of the bind library.
deps = [
"@fuchsia_sdk//bind/fuchsia.acpi:fuchsia.acpi_cc", # An SDK bind library's C++ lib.
],
)
通过构建
fuchsia.example.gizmo.bind library
是以下 C++ 头文件
(顺便提一下,示例中不包含):
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// WARNING: This file is machine generated by bindc.
#ifndef BIND_FUCHSIA_EXAMPLES_GIZMO_BIND_BINDLIB_
#define BIND_FUCHSIA_EXAMPLES_GIZMO_BIND_BINDLIB_
#include <string>
#include <bind/fuchsia/acpi/cpp/bind.h>
namespace bind_fuchsia_examples_gizmo_bind {
static const std::string MODELNAME = "fuchsia.examples.gizmo.bind.ModelName";
static const std::string GIZMOTYPE = "fuchsia.examples.gizmo.bind.GizmoType";
static const std::string GIZMOTYPE_MEM_64K = "fuchsia.examples.gizmo.bind.GizmoType.MEM_64K";
static const std::string GIZMOTYPE_MEM_128K = "fuchsia.examples.gizmo.bind.GizmoType.MEM_128K";
static const std::string GIZMOTYPE_MEM_256K = "fuchsia.examples.gizmo.bind.GizmoType.MEM_256K";
static constexpr uint32_t BIND_PCI_VID_GIZMOTRONICS = 3227993;
} // namespace bind_fuchsia_examples_gizmo_bind
#endif // BIND_FUCHSIA_EXAMPLES_GIZMO_BIND_BINDLIB_
开发者现在可以将此 C++ 头文件中的节点属性用于以下任务:
更新父驱动程序的子节点
在 Fuchsia 中,某些驱动程序会创建可让其他驱动程序绑定到的子节点。推动 create 子节点称为父驱动程序。使用新的绑定库时,主要任务是 更新父驱动程序的子节点, 绑定库
如需更新父驱动程序的子节点,请按以下步骤操作:
1. 在 build 文件中添加新的绑定库
更新父驱动程序的 build 文件,以包含新绑定库的依赖项。
下方家长驱动程序的 BUILD.bazel
文件显示,
cc_binary
目标依赖于自定义绑定库 fuchsia.example.gizmo.bind_cc
:
fuchsia_cc_driver(
name = "parent_driver",
srcs = [
"gizmo_server.h",
"parent-driver.cc",
"parent-driver.h",
],
deps = [
# This is a C++ lib from our manually created bind library.
"//src/bind_library/lib:examples.gizmo.bind_cc",
# This is a C++ lib from our manually created FIDL based bind library.
"//src/bind_library/lib:examples.gizmo_bindlib_cc",
"//src/bind_library/lib:examples.gizmo_cc",
# This is a C++ lib from an SDK FIDL based bind library.
"@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_bindlib_cc",
"@fuchsia_sdk//pkg/driver_component_cpp",
],
)
请注意,该依赖项带有 //src/bind_library/lib
前缀(而不是 @fuchsia_sdk//
)。
这表示它来自示例中的本地目录。
2. 为子节点分配节点属性
更新父驱动程序的源代码,以便新绑定中的某些节点属性 传递给子节点。
使用自动生成的 C++ 头文件
parent-driver.cc
中包含了新的绑定库,此驱动程序现在可以读取
新绑定库中的节点属性:
#include <bind/examples/gizmo/bind/cpp/bind.h>
#include <bind/examples/gizmo/cpp/bind.h>
#include <bind/fuchsia/device/fs/cpp/bind.h>
...
properties[0] =
fdf::MakeProperty(arena, 1 /* BIND_PROTOCOL */, bind_fuchsia_acpi::BIND_PROTOCOL_DEVICE);
properties[1] = fdf::MakeProperty(arena, bind_fuchsia_acpi::HID, "GOOG");
properties[2] = fdf::MakeProperty(arena, bind_examples_gizmo_bind::MODELNAME, "GIZMO3000");
properties[3] = fdf::MakeProperty(arena, bind_examples_gizmo_bind::GIZMOTYPE,
bind_examples_gizmo_bind::GIZMOTYPE_MEM_64K);
请注意,bind_fuchsia_examples_gizmo_bind
命名空间中的某些字符串变量
(请参阅自动生成的 C++ 头文件文件)
来初始化子节点的节点属性。
更新子驱动程序的绑定规则
绑定到现有驱动程序的子节点的驱动程序称为“子驱动程序”。 使用新的绑定库时,主要任务是更新子驱动程序的绑定规则, 使用新绑定库中的节点属性。基本目标是 精确的绑定规则,以保证它与 紫红色系统。
如需更新子驱动程序的绑定规则,请按以下步骤操作:
1. 在 build 文件中添加新的绑定库
更新子驱动程序的 build 文件,以包含新绑定库的依赖项
下方子驱动程序的 BUILD.bazel
文件显示,
fuchsia_driver_bytecode_bind_rules
目标具有自定义绑定库的依赖项
fuchsia.example.gizmo.bind
:
fuchsia_driver_bind_bytecode(
name = "bind_bytecode",
output = "child-driver.bindbc",
rules = "child-driver.bind",
deps = [
# This bind library is one we created manually.
"//src/bind_library/lib:examples.gizmo.bind",
# This bind library is from a FIDL library that we created manually.
"//src/bind_library/lib:examples.gizmo_bindlib",
# This bind library is from an SDK FIDL library.
"@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_bindlib",
],
)
请注意,该依赖项带有 //src/bind_library/lib
前缀(而不是 @fuchsia_sdk//
)。
这表示它来自示例中的本地目录。
2. 使用新的节点属性编写绑定规则
编写(或更新)子驱动程序的绑定规则,以便使用新绑定库中的节点属性。
子驱动程序的绑定规则 (child-driver.bind
) 显示 ModelName
和自定义绑定库 fuchsia.example.gizmo.bind
中的 GizmoType
属性用于
规则以缩小驱动程序的目标设备范围:
using fuchsia.acpi;
using examples.gizmo.bind;
...
fuchsia.BIND_PROTOCOL == fuchsia.acpi.BIND_PROTOCOL.DEVICE;
fuchsia.acpi.hid == "GOOG";
examples.gizmo.bind.ModelName == "GIZMO3000";
examples.gizmo.bind.GizmoType == examples.gizmo.bind.GizmoType.MEM_64K;
如需详细了解绑定规则,请参阅为驱动程序编写绑定规则。
附录
源代码和 SDK 在绑定库代码生成方面的差异
Bind 库代码生成教程中的大多数概念和示例都适用 发布到 Fuchsia SDK 开发环境。
不过,区别如下:
- 无法在 SDK 中生成 Rust 目标。
- C++ 库目标
cc_library
为:{target_name}_cc
(而不是:{target_name}_cpp
) 。 - 需要将 C++ 库
fuchsia_bind_cc_library
的目标添加到 如果 SDK 中不包含绑定库,请手动BUILD.bazel
。