建立複合式節點

本教學課程說明如何在 Fuchsia 系統中為複合驅動程式庫建立複合節點

複合節點規格是用來描述 Fuchsia 系統中複合節點的機制。複合節點是指具有多個父項的節點。複合驅動程式是一種驅動程式庫,會繫結至複合節點,並使用系統中由多個父節點管理的資源。

如要為複合驅動程式庫建立複合節點,您必須執行下列工作:

  • 建立複合式節點規格
  • 編寫複合驅動程式庫繫結規則 (以符合複合節點規格)

步驟如下:

  1. 準備父項規格
  2. 建立複合式節點規格
  3. 定義複合驅動程式的繫結規則

如需疑難排解問題,請參閱「偵錯複合式驅動程式庫問題」。

瞭解複合節點概念

複合節點是指有多個父項的節點。複合節點可做為多個父項節點的中央聯絡點,讓您存取這些父項節點管理的資源。當驅動程式庫繫結至複合節點時,複合驅動程式庫就能存取父項驅動程式提供的組合資源。

複合節點

圖 1. 複合節點可存取多個父項節點及其資源。

開始之前,請先熟悉下列開發概念:

重要背景概念

本教學課程假設您熟悉以下與 Fuchsia 驅動程式相關的概念:

  • 驅動程式繫結:將驅動程式與 Fuchsia 系統中的節點配對的程序。
  • 複合節點:具有多個父項節點的節點,可在 Fuchsia 系統中存取多個資源。
  • 驅動程式架構 (DFv2):新的架構,可管理 Fuchsia 中的驅動程式和節點。

什麼是複合節點規格?

複合節點規格是建立複合節點的機制。它會說明可做為複合節點父項的節點,以及可繫結至複合節點的適當複合驅動程式庫。

與元件資訊清單 (.cml) 和繫結規則 (.bind) 不同,複合式節點規格不是檔案。這是一個物件,需要由在 Fuchsia 系統中載入的驅動程式庫 (確切來說,是驅動程式庫的原始碼) 建構及新增 (使用 CompositeNodeManager 通訊協定)。

複合節點規格

圖 2. 複合節點規格是一組父項規格。

複合節點規格包含一組父項規格,每個規格代表複合節點的父項條件。一組父規格可用於以下用途:

  • 說明節點,也就是此複合節點的父項。
  • 提供屬性,用於識別複合式驅動程式庫。

複合節點規格中的每個父項規格都包含下列項目:

  • 繫結規則:用於將這個父項規格與拓樸中的節點相符的繫結規則。
  • 屬性:在複合節點的配對程序中套用的鍵/值組合,用於尋找複合驅動程式庫。(這些屬性遵循與節點屬性相同的格式)。

驅動程式庫架構如何在 Fuchsia 系統中建立複合節點?

當複合節點規格導入系統時,會發生下列事件:

  1. 複合節點規格會由 Fuchsia 系統中載入的驅動驅動程式庫新增至驅動程式架構,通常是板卡驅動程式

    複合節點規格步驟 1

  2. 驅動程式管理員會要求驅動程式索引,根據複合節點規格搜尋相符的複合式驅動程式庫。

    複合驅動程式,其繫結規則可滿足此複合節點規格中父項規格的所有屬性。(請參閱「如何將複合式驅動程式庫程式與複合式節點配對?」)

    複合節點規格步驟 2

  3. 找到複合驅動程式庫後,驅動程式管理器會要求驅動程式庫索引根據複合節點規格,搜尋系統中的節點。

    系統會比對節點屬性可滿足複合節點規格中父項規格提供的繫結規則的節點。在步驟 3 中,每個相符的節點都會成為新建立的複合節點的父節點。

    複合節點規格步驟 3

  4. 所有父項規格都相符後,驅動程式管理器會使用相符的節點做為父項,建立複合節點,最後將複合驅動程式庫 (在步驟 1 中相符) 繫結至新建立的複合節點。(複合節點會提供主要節點和節點名稱)。

    複合節點規格步驟 4

驅動程式庫架構如何將複合驅動程式庫與複合節點配對?

複合驅動程式庫的比對程序,是將複合驅動程式庫程式的繫結規則套用至複合節點規格中由父項規格提供的屬性。(請注意,這與套用父項規格繫結規則以比對拓撲中的節點不同)。

舉例來說,這些繫結規則來自複合驅動程式庫:

composite focaltech_touch;

using fuchsia.gpio;
using fuchsia.hardware.i2c;
using fuchsia.i2c;

primary node "i2c" {
  fuchsia.hardware.i2c.Service == fuchsia.hardware.i2c.Service.ZirconTransport;
  fuchsia.BIND_I2C_ADDRESS == fuchsia.i2c.BIND_I2C_ADDRESS.FOCALTECH_TOUCH;
}

node "gpio-int" {
  fuchsia.BIND_PROTOCOL == fuchsia.gpio.BIND_PROTOCOL.DEVICE;
  fuchsia.gpio.FUNCTION == fuchsia.gpio.FUNCTION.TOUCH_INTERRUPT;
}

根據這些繫結規則,相符的複合節點規格需要一個父項規格,其中屬性與 i2c 相符,以及另一個父項規格,其中屬性與 gpio-int 相符。

複合驅動程式庫與複合節點 (規格) 之間的配對成功,必須符合下列條件:

  • 所有父項規格都必須與複合驅動程式庫的繫結規則中的節點相符。

  • 複合驅動程式庫的繫結規則中,所有非選用節點都必須與父項規格相符。

    舉例來說,複合驅動程式庫中的這些繫結規則包含一個選用節點:

    composite virtio_input;
    
    using fuchsia.acpi;
    using fuchsia.hardware.pci;
    using fuchsia.pci;
    
    primary node "pci" {
        fuchsia.hardware.pci.Service == fuchsia.hardware.pci.Service.ZirconTransport;
        fuchsia.BIND_PCI_VID == fuchsia.pci.BIND_PCI_VID.VIRTIO;
        fuchsia.BIND_PCI_DID == fuchsia.pci.BIND_PCI_DID.VIRTIO_DEV_TYPE_INPUT;
    }
    
    optional node "acpi" {
        fuchsia.BIND_PROTOCOL == fuchsia.acpi.BIND_PROTOCOL.DEVICE;
    }
    

    (資料來源virtio_input.bind)

節點不必按照複合驅動程式庫的繫結規則所列的順序配對。

不過,比對結果不得模棱兩可,也就是:

  • 每個父項規格都必須對應至複合驅動程式庫的繫結規則中僅有一個節點。
  • 複合繫結規則中的每個節點最多只能與一個父項規格相符。(選用節點可能不符合任何父項規格)。

如果發生模糊的情況,驅動程式管理器會在記錄中顯示警告訊息。(目前仍會進行比對,但日後將禁止這項操作。請參閱這份相關支援單)。

父項規格繫結規則

圖 3. 每個父項規格的繫結規則會用於尋找複合節點的父項節點。

複合節點繫結規則

圖 4. 複合驅動程式的繫結規則會與複合節點的屬性相符,這些屬性是由複合節點規格中的父項規格共同提供。

繫結規則的運作方式為何?

父項規格中的繫結規則會提供「接受」和「拒絕」的屬性值清單。節點必須符合繫結規則,其節點屬性必須包含所有接受的節點屬性值,且不得包含任何遭拒的屬性值。

舉例來說,父項規格可能包含下列繫結規則:

  • 接受 fuchsia.BIND_PROTOCOL1517
  • 拒絕 fuchsia.BIND_PLATFORM_DEV_VIDIntel

使用這些繫結規則時,只有在節點包含 fuchsia.BIND_PROTOCOL 屬性的 1517 值,且不含 fuchsia.BIND_PLATFORM_DEV_VID 屬性的 Intel 值時,才能進行比對。

1. 準備父項規格

您必須先準備父項規格,才能組成複合節點規格

如要準備父項規格,請按照下列步驟操作:

  1. 在父項規格中定義繫結規則
  2. 在父項規格中定義屬性

1. 在父項規格中定義繫結規則

綁定規則可根據父項規格,找出並比對拓樸中的節點。節點的屬性會根據父規格中的繫結規則進行評估。如果相符,該節點就會成為組合節點的父項節點。

編寫繫結規則的程序

為複合節點的父項節點編寫繫結規則的程序,與繫結規則教學課程中所述的程序類似。如要判斷繫結規則,您必須先找出要繫結的每個父項節點的屬性。

如要查看節點拓樸中的每個節點屬性,您可以使用下列 ffx 指令:

ffx driver list-devices -v

這個指令會列印類似以下的項目:

Name     : i2c-1-56
Topo Path: sys/platform/i2c-0/aml-i2c/i2c/i2c-1-56
Driver   : fuchsia-boot:///#driver/i2c.so
Flags    : MUST_ISOLATE | BOUND
Proto    : ZX_PROTOCOL_I2C (24)
3 Properties
[ 1/  3] : Key fuchsia.BIND_I2C_BUS_ID        Value 0x000001
[ 2/  3] : Key fuchsia.BIND_I2C_ADDRESS       Value 0x000038
[ 3/  3] : Key "fuchsia.hardware.i2c.Service" Value "fuchsia.hardware.i2c.Service.ZirconTransport"

上述範例項目顯示 i2c-1-56 節點的以下節點屬性:

  • fuchsia.I2C_BUS_ID = 0x000001undefined
  • fuchsia.I2C_ADDRESS = 0x000038
  • fuchsia.hardware.i2c.Service = fuchsia.hardware.i2c.Service.ZirconTransport

如要查看可接受的屬性值,您可以查詢 Fuchsia 程式碼庫中的繫結程式庫 (例如 src/devices/bind 目錄)。在本例中,由於節點是 I2C 節點,因此屬性值會在 fuchsia.i2c 繫結程式庫中找到,如下所示:

extend uint fuchsia.BIND_I2C_BUS_ID {
  I2C_A0_0 = 0,
  I2C_2 = 1,
  I2C_3 = 2,
};

extend uint fuchsia.BIND_I2C_ADDRESS {
  BACKLIGHT = 0x2C,
  ETH = 0x18,
  FOCALTECH_TOUCH = 0x38,
  AMBIENTLIGHT = 0x39,
  AUDIO_CODEC = 0x48,
  GOODIX_TOUCH = 0x5d,
  TI_INA231_MLB = 0x49,
  TI_INA231_SPEAKERS = 0x40,
  TI_INA231_MLB_PROTO = 0x46,
};

除了 Fuchsia 程式碼庫中的繫結程式庫外,您也可以從 FIDL 程式庫產生繫結程式庫。在上述範例中,這是 fuchsia.hardware.i2c.Service 鍵及其值 fuchsia.hardware.i2c.Service.ZirconTransport 的屬性來源。(詳情請參閱「產生的繫結程式庫」)。

您可以使用繫結程式庫中的屬性值,重新對應節點屬性,如下所示:

  • fuchsia.BIND_I2C_BUS_ID = fuchsia.i2c.BIND_I2C_BUS_ID.I2C_2
  • fuchsia.BIND_I2C_ADDRESS = fuchsia.i2c.BIND_I2C_ADDRESS.FOCALTECH_TOUCH
  • fuchsia.hardware.i2c.Service = fuchsia.hardware.i2c.Service.ZirconTransport

您可以透過驅動程式產生的程式庫,在驅動程式庫原始碼中存取這些繫結程式庫值。(詳情請參閱「Bind 程式庫 codegen 教學課程」)。

符合這些屬性的繫結規則定義如下:

accept fuchsia.hardware.i2c.Service { fuchsia.hardware.i2c.Service.ZirconTransport }
accept BIND_I2C_BUS_ID { fuchsia.i2c.BIND_I2C_BUS_ID.I2C_2 }
accept BIND_I2C_ADDRESS { fuchsia.i2c.BIND_I2C_ADDRESS.FOCALTECH_TOUCH }

在 DFv1 中定義繫結規則

在 DFv1 中,複合節點規格是使用 DDKTL (裝置驅動程式套件範本程式庫) 編寫。用於編寫繫結規則的函式位於 composite-node-spec.h 中。

使用 DDK 程式庫和繫結程式庫 codegen 值,我們可以編寫以下內容:

const ddk::BindRule kI2cBindRules[] = {
    ddk::MakeAcceptBindRule(bind_fuchsia_hardware_i2c::SERVICE,
                            bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    ddk::MakeAcceptBindRule(bind_fuchsia::I2C_BUS_ID,
                            bind_fuchsia_i2c::BIND_I2C_BUS_ID_I2C_2),
    ddk::MakeAcceptBindRule(bind_fuchsia::I2C_ADDRESS,
                            bind_fuchsia_focaltech_platform::BIND_I2C_ADDRESS_TOUCH),
};

在 DFv2 中定義繫結規則

在 DFv2 中,複合節點規格是由 fuchsia.driver.framework FIDL 程式庫中 composite_node_spec.fidlCompositeNodeSpec 通訊協定定義。sdk/lib/driver/component/cpp 目錄中的 composite_node_spec.h 程式庫可用於簡化繫結規則的定義。

使用 CompositeNodeSpec 程式庫和繫結程式庫 codegen 值,我們可以編寫以下內容:

auto i2c_bind_rules = std::vector {
    MakeAcceptBindRule(bind_fuchsia_hardware_i2c::SERVICE,
                       bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    MakeAcceptBindRule(bind_fuchsia::I2C_BUS_ID,
                       bind_fuchsia_i2c::BIND_I2C_BUS_ID_I2C_2),
    MakeAcceptBindRule(bind_fuchsia::I2C_ADDRESS,
                       bind_fuchsia_focaltech_platform::BIND_I2C_ADDRESS_TOUCH),
};

2. 在父規格中定義屬性

除了定義節點的繫結規則,您還需要在父項規格中定義用於尋找複合式驅動程式庫的屬性。

這些屬性為鍵/值組合,用於將父項規格與複合驅動程式庫的繫結規則相符。這些屬性與節點屬性相同,採用相同的格式。屬性鍵可以是整數或字串,屬性值則可以是整數、布林值、字串或列舉型別。

在 DFv1 中定義屬性

在 DFv1 中,複合節點規格是使用 DDKTL 編寫,而用於編寫繫結規則的函式則位於 composite-node-spec.h 中。您可以使用 DDK 程式庫定義屬性,並繫結程式庫 codegen 值,如下所示:

const device_bind_prop_t kI2cProperties[] = {
    ddk::MakeProperty(bind_fuchsia_hardware_i2c::SERVICE,
                      bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    ddk::MakeProperty(bind_fuchsia::I2C_ADDRESS,
                      bind_fuchsia_focaltech_platform::BIND_I2C_ADDRESS_TOUCH),
};

在 DFv2 中定義屬性

在 DFv2 中,會為 fuchsia.driver.framework FIDL 程式庫中的 composite_node_spec.fidl 編寫複合節點規格。//sdk/lib/driver/component/cpp 中的 node_add_args.h 程式庫可用來簡化屬性定義。您可以使用 CompositeNodeSpec 程式庫定義屬性,並繫結程式庫 codegen 值,如下所示:

auto i2c_properties[] = std::vector {
    ddk::MakeProperty(bind_fuchsia::I2C_ADDRESS,
                      bind_fuchsia_focaltech_platform::BIND_I2C_ADDRESS_TOUCH),
};

2. 建立複合式節點規格

建立複合節點規格時,需要在驅動程式管理器中定義並新增一組父項規格。

複合節點規格會由 Fuchsia 系統中載入的驅動驅動程式庫新增至驅動程式架構,通常是板卡驅動程式庫。(如要進一步瞭解這個程序,請參閱「驅動程式庫架構如何在 Fuchsia 系統中建立複合節點?」)。

在 DFv1 中新增複合節點規格

在 DFv1 中,驅動程式庫可以透過 DDKTLDdkAddCompositeNodeSpec() 函式新增複合節點規格。

驅動程式必須先在 composite-node-spec.h 程式庫中定義 CompositeNodeSpec 物件。使用上一節中的範例繫結規則和屬性,您可以定義具有 I2C 父項規格的 CompositeNodeSpec 物件,如下所示:

const ddk::BindRule kI2cBindRules[] = {
    ddk::MakeAcceptBindRule(bind_fuchsia_hardware_i2c::SERVICE,
                            bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    ddk::MakeAcceptBindRule(bind_fuchsia::I2C_BUS_ID,
                            bind_fuchsia_i2c::BIND_I2C_BUS_ID_I2C_2),
    ddk::MakeAcceptBindRule(bind_fuchsia::I2C_ADDRESS,
                            bind_fuchsia_focaltech_platform::BIND_I2C_ADDRESS_TOUCH),
};

const device_bind_prop_t kI2cProperties[] = {
    ddk::MakeProperty(bind_fuchsia_hardware_i2c::SERVICE,
                      bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    ddk::MakeProperty(bind_fuchsia::I2C_ADDRESS,
                      bind_fuchsia_focaltech_platform::BIND_I2C_ADDRESS_TOUCH),
};

auto spec = ddk::CompositeNodeSpec(kI2cBindRules, kI2cProperties);

您可以使用 AddParentSpec() 函式新增任何其他節點。舉例來說,如果要為 GPIO 解讀針腳新增父項規格,可以編寫以下內容:

const ddk::BindRule kGpioInterruptRules[] = {
    ddk::MakeAcceptBindRule(bind_fuchsia::PROTOCOL,
                            bind_fuchsia_gpio::BIND_PROTOCOL_DEVICE),
    ddk::MakeAcceptBindRule(bind_fuchsia::GPIO_PIN,
                bind_fuchsia_amlogic_platform_s905d2::GPIOZ_PIN_ID_PIN_4),
};

const device_bind_prop_t kGpioInterruptProperties[] = {
    ddk::MakeProperty(bind_fuchsia::PROTOCOL,
                      bind_fuchsia_gpio::BIND_PROTOCOL_DEVICE),
    ddk::MakeProperty(bind_fuchsia_gpio::FUNCTION,
                      bind_fuchsia_gpio::FUNCTION_TOUCH_INTERRUPT)};

desc.AddParentSpec(kGpioInterruptRules, kGpioInterruptProperties);

CompositeNodeSpec 物件就緒後,您可以使用 DdkAddCompositeNodeSpec() 新增該物件,其中 spec 是包含複合節點規格的物件,例如:

auto status = DdkAddCompositeNodeSpec("ft3x27_touch", spec);

由於 CompositeNodeSpec 物件遵循建構工具模式,因此可以簡化為:

auto status =
     DdkAddCompositeNodeSpec("ft3x27_touch",
          ddk::CompositeNodeSpec(kFocaltechI2cRules, kFocaltechI2cProperties)
              .AddParentSpec(kGpioInterruptRules, kGpioInterruptProperties)
              .set_metadata(metadata);

在 DFv2 中新增複合節點規格

在 DFv2 中,我們使用 fuchsia.driver.framework FIDL API 中的 CompositeNodeManager 通訊協定,新增複合節點規格:

@discoverable
protocol CompositeNodeManager {
    /// Add the given spec to the driver manager.
    AddSpec(CompositeNodeSpec) -> () error CompositeNodeSpecError;
};

將複合節點規格新增至平台匯流排

如果複合節點需要平台匯流排中節點的父項,則電路板驅動程式庫可以透過 platform_bus.fidl API 新增複合節點規格。這項規定適用於 DFv1 和 DFv2。

/// Adds a composite node specification to the bus. This will add a platform device specified
/// by |node| and insert a node into the composite node specification that matches the device.
AddCompositeNodeSpec(struct {
    node Node;
    spec fuchsia.driver.framework.CompositeNodeSpec;
}) -> () error zx.Status;

平台匯流排 API 會使用 composite_node_spec.fidl 中定義的相同 CompositeNodeSpec 結構體。

舉例來說,假設我們定義了下列複合節點規格:

std::vector<fuchsia_driver_framework::BindRule> bind_rules = {
    fdf::MakeAcceptBindRule(bind_fuchsia_hardware_i2c::SERVICE,
        bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    fdf::MakeAcceptBindRule(bind_fuchsia::I2C_ADDRESS,
        bind_fuchsia_i2c::BIND_I2C_ADDRESS_BACKLIGHT),
};

std::vector<fuchsia_driver_frameowork::Node> properties = {
    fdf::MakeProperty(bind_fuchsia_hardware_i2c::SERVICE,
        bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT),
    fdf::MakeProperty(bind_fuchsia::I2C_ADDRESS,
        bind_fuchsia_i2c::BIND_I2C_ADDRESS_BACKLIGHT),
};

std::vector<fuchsia_driver_framework::ParentSpec> spec = {
    {{bind_rules, properties}}
};

(如要進一步瞭解上述範例中使用的程式庫,請參閱「在 DFv2 中定義屬性」和「在 DFv2 中定義繫結規則」)。

定義複合節點規格後,板卡驅動程式庫就能透過 PlatformBus FIDL 通訊協定連線至平台匯流排,並使用用戶端端點呼叫 AddCompositeNodeSpec()

AddCompositeNodeSpec() 呼叫會將平台裝置的父項規格 (由節點欄位中的資料建立) 插入指定的複合節點規格,並將此修改過的複合節點規格新增至驅動程式庫架構。然後建立並新增平台裝置,例如:

fpbus::Node dev;
dev.name() = "backlight";
dev.vid() = PDEV_VID_TI;  // 0x10
dev.pid() = PDEV_PID_TI_LP8556; // 0x01
dev.did() = PDEV_DID_TI_BACKLIGHT;  // 0x01

auto endpoints =
    fdf::CreateEndpoints<fuchsia_hardware_platform_bus::PlatformBus>();
if (endpoints.is_error()) {
    return endpoints.error_value();
}

fdf::WireSyncClient<fuchsia_hardware_platform_bus::PlatformBus> pbus =
    endpoints->client;
auto result = pbus.buffer(arena)->AddCompositeNodeSpec(
fidl::ToWire(fidl_arena, dev),
fidl::ToWire(fidl_arena, spec), false);

if (!result.ok()) {
    FDF_LOG(ERROR, "AddCompositeNodeSpec request failed: %s",
               result.FormatDescription().data());
    return result.status();
}

呼叫 AddCompositeNodeSpec() 後,下列複合節點規格會新增至驅動程式庫架構:

Name      : backlight
Driver    : fuchsia-boot:///#meta/ti-lp8556.cm
Nodes     : 2
Node 0    : None
  3 Bind Rules
  [ 1/ 3] : Accept "fuchsia.BIND_PLATFORM_DEV_VID" { 0x000010 }
  [ 2/ 3] : Accept "fuchsia.BIND_PLATFORM_DEV_PID" { 0x000001 }
  [ 2/ 3] : Accept "fuchsia.BIND_PLATFORM_DEV_DID" { 0x000001 }
  3 Properties
  [ 1/ 3] : Key "fuchsia.BIND_PLATFORM_DEV_VID"   Value 0x000010
  [ 2/ 3] : Key "fuchsia.BIND_PLATFORM_DEV_PID"   Value 0x000001
  [ 3/ 3] : Key "fuchsia.BIND_PLATFORM_DEV_DID"   Value 0x000001
Node 1    : None
  2 Bind Rules
  [ 1/ 2] : Accept "fuchsia.hardware.i2c.Service" { "fuchsia.hardware.i2c.Service.ZirconTransport" }
  [ 2/ 2] : Accept "fuchsia.BIND_I2C_ADDRESS"     { 0x00002C }
  2 Properties
  [ 1/ 2] : Key "fuchsia.hardware.i2c.Service" Value "fuchsia.hardware.i2c.Service.ZirconTransport"
  [ 2/ 2] : Key "fuchsia.BIND_I2C_ADDRESS"     Value 0x00002C
}

上方複合節點規格範例中顯示的第一個節點 (Node 0) 與從 AddCompositeNodeSpec() 建立的平台裝置相符。第一個父項規格是由 AddCompositeSpec() 插入,並且鎖定與平台裝置相符,其中包含 VID, PID 的繫結規則和屬性,以及 fpbus::Node dev 提供的 DID。其餘的上層規範則來自傳入的複合節點規範。

3. 定義複合式驅動程式庫的繫結規則

定義複合節點規格後,您就可以開始為複合驅動程式庫編寫繫結規則,這些規則會與根據複合節點規格建立的複合節點相符。

為複合驅動程式庫編寫繫結規則的程序,與為驅動程式庫編寫繫結規則的程序類似。

前幾節的範例在其父規格中包含下列屬性:

i2c parent specification properties {
     fuchsia.hardware.i2c.Service: fuchsia.hardware.i2c.Service.ZirconTransport,
     fuchsia.BIND_I2C_ADDRESS: fuchsia.focaltech.platform.BIND_I2C_ADDRESS_TOUCH,
}

gpio-interrupt parent specification properties {
     fuchsia.BIND_PROTOCOL: fuchsia.gpio.BIND_PROTOCOL_DEVICE,
     fuchsia.gpio.FUNCTION: fuchsia.gpio.FUNCTION.TOUCH_INTERRUPT,
}

如果您想將上述屬性繫結至複合節點規格,可以編寫下列複合繫結規則,以符合目標父項規格:

composite focaltech_touch;

using fuchsia.gpio;
using fuchsia.hardware.i2c;
using fuchsia.i2c;

primary node "i2c" {
  fuchsia.hardware.i2c.Service == fuchsia.hardware.i2c.Service.ZirconTransport;
  fuchsia.BIND_I2C_ADDRESS == fuchsia.i2c.BIND_I2C_ADDRESS.FOCALTECH_TOUCH;
}

node "gpio-int" {
  fuchsia.BIND_PROTOCOL == fuchsia.gpio.BIND_PROTOCOL.DEVICE;
  fuchsia.gpio.FUNCTION == fuchsia.gpio.FUNCTION.TOUCH_INTERRUPT;
}

附錄

偵錯合成驅動程式庫問題

如要確認複合節點是否已成功建立,並嘗試繫結複合驅動程式庫,您可以查看記錄檔,並尋找類似下列行的陳述式:

Binding driver fuchsia-boot:///#meta/focaltech.cm

如要確認已成功新增複合節點規格,並與複合驅動程式庫相符,請執行下列指令:

ffx driver list-composite-node-specs -v

這個指令會輸出類似以下的內容:

Name      : ft3x27_touch
Driver    : fuchsia-boot:///#meta/focaltech.cm
Nodes     : 2
Node 0    : "i2c" (Primary)
  3 Bind Rules
  [ 1/ 3] : Accept "fuchsia.hardware.i2c.Service" { "fuchsia.hardware.i2c.Service.ZirconTransport" }
  [ 2/ 3] : Accept "fuchsia.BIND_I2C_BUS_ID" { 0x000001 }
  [ 3/ 3] : Accept "fuchsia.BIND_I2C_ADDRESS" { 0x000038 }
  2 Properties
  [ 1/ 2] : Key "fuchsia.hardware.i2c.Service" Value "fuchsia.hardware.i2c.Service.ZirconTransport"
  [ 2/ 2] : Key "fuchsia.BIND_I2C_ADDRESS"     Value 0x000038
Node 1    : "gpio-int"
  2 Bind Rules
  [ 1/ 2] : Accept "fuchsia.BIND_PROTOCOL" { 0x000014 }
  [ 2/ 2] : Accept "fuchsia.BIND_GPIO_PIN" { 0x000004 }
  2 Properties
  [ 1/ 2] : Key "fuchsia.BIND_PROTOCOL"        Value 0x000014
  [ 2/ 2] : Key "fuchsia.gpio.FUNCTION"        Value "fuchsia.gpio.FUNCTION.TOUCH_INTERRUPT"

如果複合節點規格沒有相符的複合驅動程式庫,指令會輸出類似以下的內容:

Name      : focaltech_touch
Driver    : None
Nodes     : 2
Node 0    : None
  3 Bind Rules
  [ 1/ 3] : Accept "fuchsia.hardware.i2c.Service" { "fuchsia.hardware.i2c.Service.ZirconTransport" }
  [ 2/ 3] : Accept "fuchsia.BIND_I2C_BUS_ID" { 0x000001 }
  [ 3/ 3] : Accept "fuchsia.BIND_I2C_ADDRESS" { 0x000038 }
  1 Properties
  [ 1/ 2] : Key "fuchsia.hardware.i2c.Service" Value "fuchsia.hardware.i2c.Service.ZirconTransport"
  [ 2/ 2] : Key "fuchsia.BIND_I2C_ADDRESS"     Value 0x000038
Node 1    : None
  2 Bind Rules
  [ 1/ 2] : Accept "fuchsia.BIND_PROTOCOL" { 0x000014 }
  [ 2/ 2] : Accept "fuchsia.BIND_GPIO_PIN" { 0x000004 }
  2 Properties
  [ 1/ 2] : Key "fuchsia.BIND_PROTOCOL"        Value 0x000014
  [ 2/ 2] : Key "fuchsia.gpio.FUNCTION"        Value "fuchsia.gpio.FUNCTION.TOUCH_INTERRUPT

如要進一步瞭解 ffx driver 指令,請參閱「查看驅動程式庫資訊」。