本指南將逐步說明在 Fuchsia SDK 開發環境中建立新繫結程式庫的相關工作 (該環境使用 Bazel 建構系統)。
在 Fuchsia 驅動程式庫開發中,繫結程式庫可輕鬆協調下列工作:
Fuchsia SDK 包含一組繫結程式庫,可用於編寫驅動程式的繫結規則。不過,有時只使用現有的繫結程式庫,可能不足以編寫驅動程式的精確建構規則。在這種情況下,您可能需要建立新的繫結程式庫,為驅動程式庫及其目標節點定義一組自訂繫結屬性。
本指南中的開發情境
當新的繫結程式庫推出時,有兩個群組可能會想使用這個程式庫,這兩個群組的職責各不相同:一個群組負責管理父項驅動程式,另一個群組則負責處理子項驅動程式。
圖表 1。節點拓撲,顯示兩個驅動程式之間的父項/子項關係。
圖 1 顯示具有兩個驅動程式的節點拓撲:parent-driver 和 child-driver。現在假設有一群平台開發人員為 Fuchsia 系統中的內建 ACPI 裝置編寫驅動程式庫 (parent-driver),而一群裝置開發人員則為目標節點為 bindlib-child 的新 ACPI 裝置編寫驅動程式庫 (child-driver)。
在這個情境中,會發生下列事件:
建立新的繫結程式庫:建立新的繫結程式庫,為新的 ACPI 裝置定義節點屬性。
這個新的自訂繫結程式庫隨後會在兩個群組之間共用:
更新父項驅動程式的子節點 - 管理
parent-driver的開發人員會將新的節點屬性指派給子節點bindlib-child。更新子項驅動程式的繫結規則: 開發人員使用新的節點屬性,為
child-driver編寫繫結規則。
建立新的繫結程式庫
建立新的繫結程式庫,讓開發人員在 Fuchsia 系統中精確識別特定目標裝置。
如要建立新的繫結程式庫,請按照下列步驟操作:
1. 撰寫新的繫結程式庫
編寫繫結程式庫,定義一組新的自訂節點屬性。
新的繫結程式庫可能如下所示 (請參閱繫結程式庫範例的 lib 目錄):testlibrary.bind
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.bazel),讓開發人員自動產生程式庫構件。
以下建構目標會在範例繫結程式庫的 BUILD.bazel 檔案中,定義名為 fuchsia.example.gizmo.bind 的新 C++ 繫結程式庫:
# 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 中,部分驅動程式會建立子節點,供其他驅動程式繫結。建立子節點的驅動程式稱為父項驅動程式。使用新的繫結程式庫時,主要工作是更新父項驅動程式的子節點,以便從新的繫結程式庫接收節點屬性。
如要更新父項驅動程式的子項節點,請按照下列步驟操作:
1. 在建構檔案中新增繫結程式庫
更新父項驅動程式庫的建構檔案,加入新繫結程式庫的依附元件。
父項驅動程式的 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. 將節點屬性指派給子節點
更新父項驅動程式庫的原始碼,將新繫結程式庫的特定節點屬性傳遞至子項節點。
有了 parent-driver.cc 中新繫結程式庫的自動產生 C++ 標頭檔案,這個驅動程式庫現在可以從新繫結程式庫讀取節點屬性:
#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++ 標頭檔案) 會用於初始化子節點的節點屬性。
更新子項驅動程式的繫結規則
繫結至現有驅動程式庫子節點的驅動程式稱為子項驅動程式庫。使用新的繫結程式庫時,主要工作是更新子項驅動程式的繫結規則,以便使用新繫結程式庫中的節點屬性。最終目標是為驅動程式庫編寫更精確的繫結規則,確保驅動程式與 Fuchsia 系統中的目標節點相符。
如要更新孩子駕駛人的繫結規則,請按照下列步驟操作:
1. 在建構檔案中新增繫結程式庫
更新子項驅動程式庫的建構檔案,加入新繫結程式庫的依附元件
子項驅動程式的 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) 顯示,規則會使用自訂繫結程式庫 fuchsia.example.gizmo.bind 中的 ModelName 和 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 之間繫結程式庫程式碼產生的差異
繫結程式庫程式碼產生教學課程中的大部分概念和範例,都適用於 Fuchsia SDK 開發環境。
不過,兩者有以下差異:
- SDK 無法產生 Rust 目標。
- SDK 中的 C++ 程式庫目標為
cc_library(而非:{target_name}_cpp)。:{target_name}_cc - 如果 SDK 未納入繫結程式庫,則必須手動在
BUILD.bazel中新增 C++ 程式庫fuchsia_bind_cc_library的目標。