本指南逐步介绍了如何使用
i2c_temperature
示例驱动程序。
要让驱动程序绑定到节点(代表硬件
或虚拟设备),驱动程序的绑定规则必须与
节点。在本指南中,我们将为 i2c_temperature
示例编写绑定规则。
驱动程序,使其与 i2c-child
节点的节点属性相匹配。
i2c_controller
驱动程序会创建一个名为 i2c-child
的子节点用于测试
i2c_temperature
示例驱动程序。我们可以使用此 i2c_controller
驱动程序来
确定 i2c-child
节点的节点属性,并将匹配的
i2c_temperature
的绑定规则。
在开始之前,编写绑定规则要求熟悉相关概念 (在驱动程序绑定中)。
具体步骤如下:
1. 确定节点属性
您可以通过以下任一方式确定目标节点的节点属性:
使用 ffxDriver 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
。 - 属性键“
fuchsia.BIND_I2C_ADDRESS
”,整数值为0xFF
。
在驱动程序源代码中查找节点属性
添加子节点时,驱动程序可以为节点提供节点属性。 查看将目标节点创建为子节点的驱动程序的源代码 节点可帮助您确定要包含在绑定规则中的节点属性。
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
。 - 属性键“
fuchsia.BIND_I2C_ADDRESS
”,整数值为0xFF
。
2. 编写绑定规则
知道要匹配的节点属性后,您就可以使用 来为驱动程序编写绑定规则。
在上一部分中,我们已确定 i2c-child
节点具有
以下节点属性:
- 属性键
fuchsia.hardware.i2c
,枚举值为fuchsia.hardware.i2c.Service.ZirconTransport
。 - 属性键“
fuchsia.BIND_I2C_ADDRESS
”,整数值为0xFF
。
为了匹配这些属性,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
库,因此构建目标包含绑定库
作为 build 依赖项。
如需确定绑定规则中使用了哪些绑定库,您可以查看
驱动程序源代码在 i2c-child
节点的节点属性中,
第一个属性键“fuchsia.hardware.i2c.Service
”来自生成的绑定
库:
// 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>
这些绑定库在驱动程序的 build 中具有相应的依赖项
规则。请在 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;
};