寫入驅動程式的繫結規則

本指南將逐步說明使用 i2c_temperature 範例驅動程式庫。

可讓驅動程式庫繫結至代表硬體的「節點」 或虛擬裝置),驅動程式的繫結規則必須與 節點。在本指南中,我們將為 i2c_temperature 範例撰寫繫結規則 驅動程式庫,使其與 i2c-child 節點的節點屬性相符。

i2c_controller 驅動程式庫會建立名為 i2c-child 的子節點來進行測試 i2c_temperature 範例驅動程式庫。我們可以使用此 i2c_controller 驅動程式庫 找出 i2c-child 節點的節點屬性並寫入 i2c_temperature 的繫結規則。

您必須先熟悉概念,才能撰寫繫結規則 驅動程式繫結中。

步驟如下:

  1. 識別節點屬性
  2. 編寫繫結規則
  3. 為繫結規則新增 Bazel 建構目標

1. 識別節點屬性

您可以透過下列任一方式識別目標節點的節點屬性:

使用 ffx 驅動程式庫清單裝置指令

如要列印 Fuchsia 系統中每個節點的屬性,請執行下列指令:

ffx driver list-devices -v

這個指令會以下列格式顯示節點的屬性:

Name     : i2c-child
Moniker  : root.sys.platform.pt.acpi.FWCF.i2c-child
Driver   : None
3 Properties
[ 1/  3] : Key "fuchsia.hardware.i2c.Service"  Value Enum(fuchsia.hardware.i2c.Service.ZirconTransport)
[ 2/  3] : Key fuchsia.BIND_I2C_ADDRESS        Value 0x0000ff
[ 3/  3] : Key "fuchsia.platform.DRIVER_FRAMEWORK_VERSION" Value 0x000002

上述輸出內容顯示 i2c-child 節點具有下列節點屬性:

  • 屬性鍵 fuchsia.hardware.i2c.Service 的列舉值 fuchsia.hardware.i2c.Service.ZirconTransport
  • 具有整數值 0xFF 的屬性鍵 fuchsia.BIND_I2C_ADDRESS

在驅動程式庫原始碼中查詢節點屬性

新增子節點時,驅動程式可提供節點屬性給節點。 查看建立做為子項目標節點的驅動程式庫原始碼 有助於找出要納入繫結規則的節點屬性。

i2c_controller 驅動程式庫會建立名為 i2c-child 的子節點,且該子節點會 i2c_temperature 樣本驅動程式庫繫結。檢查 Deployment 的原始碼 i2c_controller 驅動程式庫,用於識別傳遞至此項目的節點屬性 子節點:

// Set the properties of the node for drivers to target.
auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
properties[0] = fdf::MakeProperty(arena, bind_fuchsia_hardware_i2c::SERVICE,
                                  bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT);
properties[1] = fdf::MakeProperty(arena, 0x0A02 /* BIND_I2C_ADDRESS */, 0xff);

此程式碼顯示建立 i2c-child 節點時具有下列繫結 資源:

  • 屬性鍵 fuchsia.hardware.i2c.Service 的列舉值 fuchsia.hardware.i2c.Service.ZirconTransport
  • 具有整數值 0xFF 的屬性鍵 fuchsia.BIND_I2C_ADDRESS
,瞭解如何調查及移除這項存取權。

2. 寫入繫結規則

知道要比對的節點屬性後,即可使用 編寫驅動程式的繫結規則。

在上一節中,我們發現 i2c-child 節點具有 下列節點屬性:

  • 屬性鍵 fuchsia.hardware.i2c 的列舉值 fuchsia.hardware.i2c.Service.ZirconTransport
  • 具有整數值 0xFF 的屬性鍵 fuchsia.BIND_I2C_ADDRESS

為比對這些屬性,i2c_temperature 驅動程式庫會宣告下列內容 繫結規則:

using fuchsia.hardware.i2c;

fuchsia.hardware.i2c.Service == fuchsia.hardware.i2c.Service.ZirconTransport;
fuchsia.BIND_I2C_ADDRESS == 0xFF;

BIND_ 開頭的整數節點屬性鍵 (定義為 Fuchsia 來源樹狀結構中的 binding_priv.h) 是舊資源 目前在繫結編譯器中以硬式編碼方式寫入金鑰。請參閱下列定義 來自binding_priv.hBIND_I2C_ADDRESS

#define BIND_I2C_ADDRESS 0x0A02

在繫結規則中使用這類金鑰時,其前置字串為 fuchsia.

3. 為繫結規則新增 Bazel 建構目標

編寫驅動程式的繫結規則後,您必須更新驅動程式 BUILD.bazel 檔案,使用 fuchsia_driver_bytecode_bind_rules() 範本:

fuchsia_driver_bind_bytecode(
    name = "bind_bytecode",
    output = "i2c_temperature.bindbc",
    rules = "i2c_temperature.bind",
    deps = [
        "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_bindlib",
    ],
)

針對繫結規則中使用的每個程式庫,將程式庫新增為 建構目標例如,i2c_temperature 範例驅動程式庫的繫結規則會使用 fuchsia.hardware.i2c 程式庫,因此建構目標包含繫結程式庫 做為建構依附元件

如要判斷繫結規則中使用的繫結程式庫,請參閱 取得驅動程式庫原始碼在 i2c-child 節點的節點屬性中, 第一個屬性鍵 fuchsia.hardware.i2c.Service 來自產生的繫結 程式庫的 FIDL 通訊協定版本:

// Set the properties of the node for drivers to target.
auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
properties[0] = fdf::MakeProperty(arena, bind_fuchsia_hardware_i2c::SERVICE,
                                  bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT);
properties[1] = fdf::MakeProperty(arena, 0x0A02 /* BIND_I2C_ADDRESS */, 0xff);

前置字串 fuchsia_hardware_i2c 表示這個節點屬性的鍵和 值定義於下列標頭中:

#include <bind/fuchsia/hardware/i2c/cpp/bind.h>

這些繫結程式庫的驅動程式庫版本會有對應的依附元件 不過,編寫這類演算法並不容易 因為我們無法寫出所有可能的規則請查看 i2c_controller 中的以下 fuchsia.hardware.i2c 依附元件 二進位目標:

fuchsia_cc_driver(
    name = "i2c_controller",
    srcs = [
        "i2c_controller.cc",
        "i2c_controller.h",
        "i2c_server.cc",
        "i2c_server.h",
    ],
    deps = [
        "//src/i2c_temperature/lib",
        "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_bindlib_cc",
        "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_llcpp_cc",
        "@fuchsia_sdk//pkg/driver_component_cpp",
    ],
)

附錄

NodeProperty 和 NodeAddArgs 結構

節點屬性會以 NodeProperty 結構體表示 fuchsia.driver.framework FIDL 程式庫:

/// Definition of a property for a node. A property is commonly used to match a
/// node to a driver for driver binding.
type NodeProperty = table {
    /// Key for the property.
    1: key NodePropertyKey;

    /// Value for the property.
    2: value NodePropertyValue;
};

接著,系統會使用 NodeAddArgs 將節點屬性傳遞至子節點 struct:

/// Arguments for adding a node.
type NodeAddArgs = table {
    /// Name of the node.
    1: name string:MAX_NODE_NAME_LENGTH;

    /// Capabilities to offer to the driver that is bound to this node.
    2: offers vector<fuchsia.component.decl.Offer>:MAX_OFFER_COUNT;

    /// Functions to provide to the driver that is bound to this node.
    3: symbols vector<NodeSymbol>:MAX_SYMBOL_COUNT;

    /// Properties of the node.
    4: properties vector<NodeProperty>:MAX_PROPERTY_COUNT;
};