本指南將逐步說明如何使用 i2c_temperature
範例驅動程式編寫繫結規則。
驅動程式庫的繫結規則必須與節點的節點屬性相符,才能繫結至「節點」 (代表硬體或虛擬裝置)。在本指南中,我們會為 i2c_temperature
範例驅動程式編寫繫結規則,使其與 i2c-child
節點的節點屬性相符。
i2c_controller
驅動程式庫會建立一個名為 i2c-child
的子節點,用於測試 i2c_temperature
範例驅動程式庫。我們可以使用此 i2c_controller
驅動程式庫來識別 i2c-child
節點的節點屬性,並寫入 i2c_temperature
相符的繫結規則。
開始編寫繫結規則之前,您需要熟悉驅動程式繫結中的概念。
步驟如下:
1. 識別節點屬性
您可以透過下列任一方式識別目標節點的節點屬性:
使用 ffx 驅動程式庫 list-devices 指令
如要列印 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
範例驅動程式庫會繫結至該節點。檢查 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.h
的 BIND_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 結構體
節點屬性是以 fuchsia.driver.framework
FIDL 程式庫中的 NodeProperty
結構表示:
/// 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
結構傳遞至子節點:
/// 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;
};