RFC-0197:複合節點群組 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 支援在執行階段定義複合。 |
問題 | |
蓋爾特變化 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2022-11-01 |
審查日期 (年-月-日) | 2022-09-26 |
摘要
這個 RFC 提議在執行階段,定義複合節點的方式 驅動程式架構 v2 (DFv2)
提振精神
背景
在驅動程式架構 v1 (DFv1) 中,驅動程式可建立
複合節點
在執行階段透過 AddComposite()
函式執行驅動程式會定義繫結
複合的父項和繫結屬性和驅動程式管理器的規則
建立複合節點做為驅動程式庫的子項。另一個驅動程式庫會繫結至
複合節點
在 DFv2 中,複合驅動程式會透過 繫結規則 是以驅動程式庫繫結語言編寫的靜態檔案司機抵達時 驅動程式執行器會收集與 ,然後建立複合節點。複合驅動程式庫 繫結至節點
問題
由於複合驅動程式只能以靜態方式定義複合節點,因此無法
完全取代 DFv1 的 AddComposite()
功能。這樣可以避免一些駕駛人
就必須遷移至 DFv2
某些複合節點只會在執行階段得知,因此不可能 在複合驅動程式中定義的舉例來說,ACPI 匯流排驅動程式會建立 ACPI 複合節點匯流排驅動程式啟動後,會在 ACPI 中讀取文字 並據此建立節點
靜態繫結規則也會使撰寫跨欄複合材質的困難 因為繫結規則需要瞭解建構時的節點屬性 讓應用程式從可以最快做出回應的位置 回應使用者要求舉例來說,觸控複合驅動程式庫可能需要一個節點用於 GPIO 接腳 依特定功能設計GPIO 接腳會因遊戲板而異, 難以撰寫各節點通用的主機板繫結規則。
相關人員
講師:cpu@google.com
審查人員:surajmalhotra@google.com (FDF)、dgilhooley@google.com (FDF)
諮詢:駕駛團隊成員
社交功能:
Tq-driver 共用了 RFC 草稿
設計
需求條件
這個設計的目標是建立一種機制,讓駕駛人 下列何者必須是動態的動態節點:
- 複合節點中每個父項的繫結規則
- 用於比對複合節點與複合驅動程式庫的繫結屬性
- 複合節點中的父項。容器可能會在執行階段中確定 複合節點應包含特定父項
此外,DFv1 和 DFv2 也必須支援這項機制。隸屬於
轉換至 DFv2,所有 DFv1 驅動程式都必須從 AddComposite()
複合型驅動程式
總覽
本提案在驅動程式架構中新增 API,供駕駛人用於 定義裝置節點群組
當驅動程式庫定義節點群組時,程序如下:
- 驅動程式管理器要求驅動程式庫索引找出複合式驅動程式庫 與節點群組相符
- 找出相符的複合驅動程式庫後,驅動程式管理器會找出 每個節點代表的相符裝置節點
- 只要每個節點表示法都相符,驅動程式管理器就會建立 包含節點做為父項的複合節點,並將其繫結至複合節點 驅動程式庫。主要節點和節點名稱由複合驅動程式庫提供
節點表示法
群組中的每個節點表示法皆定義如下:
- 繫結規則:比對節點表示法與裝置的規則 節點
- 繫結屬性 - 節點表示法中的繫結屬性 會用來比對複合式驅動程式庫的靜態繫結規則
節點群組繫結規則
繫結規則由接受和遭拒的繫結屬性值清單組成。 如要符合繫結規則,繫結的屬性必須包含所有已接受 繫結屬性值,而不是任何遭拒的屬性值。舉例來說 群組節點包含繫結規則:
- 接受
fuchsia.BIND_PROTOCOL
值:15 和 17 - 拒絕
fuchsia.BIND_PLATFORM_DEV_VID
值「Intel」
接著,如果裝置包含 15 或 17 的
fuchsia.BIND_PROTOCOL
屬性,不含「Intel」值
fuchsia.BIND_PLATFORM_DEV_VID
屬性。
複合式繫結規則中的選用節點
由於某些父項的可用性只能在執行階段得知,因此複合 驅動程式必須能支援選用節點方法是透過繫結語言 需要更新,好讓複合驅動程式將節點標示為「非必要」:
primary node "sysmem" {
fuchsia.BIND_PROTOCOL == fuchsia.sysmem.BIND_PROTOCOL.DEVICE;
}
optional node "acpi" {
fuchsia.BIND_PROTOCOL == fuchsia.acpi.BIND_PROTOCOL.DEVICE;
}
比對複合驅動程式
比對程序會透過將複合驅動程式庫程式的繫結規則套用到 節點表示法繫結屬性。符合下列情況時,比對成功 已完成:
- 所有節點表示法都必須與複合式繫結規則中的節點相符
- 所有非選擇性的複合繫結規則節點都必須與節點相符 兩者的向量表示法
- 比對不會模稜兩可:
- 每個節點表示法只能對應一個複合式繫結 規則節點
- 節點表示法與複合中的相同節點不得比對 繫結規則
- 節點不需要依序比對
如果發生不明確的情況,系統會顯示警告訊息。
節點群組 API
驅動程式必須使用 FIDL 透過 NodeGroupManager
新增節點群組
套用至 fuchsia.driver.framework
FIDL 程式庫中的通訊協定:
device_group.fidl
@discoverable
protocol NodeGroupManager {
AddNodeGroup(fuchsia.driver.framework.NodeGroup) -> (struct {}) error zx.status;
};
節點群組以 FIDL 表示:
/// Represents the conditions for evaluating the device
/// group properties.
type Condition = strict enum {
ACCEPT = 0;
REJECT = 1;
};
/// Represents a bind rule for a node group node.
type BindRule = struct {
/// Property key.
key NodePropertyKey;
/// Condition for evaluating the property values in
/// the matching process. The values are accepted or
/// rejected based on the condition.
condition Condition;
/// A list of property values. Must not be empty. The property
/// values must be the same type.
values vector<NodePropertyValue>:MAX_PROPERTY_COUNT;
};
/// Struct that represents a node in a node group.
type NodeRepresentation = struct {
/// Bind rules for the node group node. Keys must be unique.
bind_rules: vector<BindRule>:MAX_PROPERTY_COUNT;
/// Properties used for matching composite bind rules. Keys must be unique.
bind_properties vector<NodeProperty>:MAX_PROPERTY_COUNT;
};
/// Struct that represents a node group.
type NodeGroup = table {
/// The node group's name.
1: name string:MAX;
/// The nodes in the node group.
2: nodes vector<NodeRepresentation>:MAX;
};
*NodeProperty 是在 Topology.fidl 中定義
範例:焦點技術觸控驅動程式
DFv1 定義
在 DFv1 中,焦距觸控驅動程式包含下列繫結規則: fuchsia.platform;
fuchsia.BIND_COMPOSITE == 1;
fuchsia.BIND_PLATFORM_DEV_VID == fuchsia.platform.BIND_PLATFORM_DEV_VID.GENERIC;
fuchsia.BIND_PLATFORM_DEV_DID == fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH;
複合裝置是在 astro-touch
中定義:
// Composite binding rules for focaltech touch driver.
const zx_bind_inst_t ft_i2c_match[] = {
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
BI_ABORT_IF(NE, BIND_I2C_BUS_ID, ASTRO_I2C_2),
BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, I2C_FOCALTECH_TOUCH_ADDR),
};
const zx_bind_inst_t goodix_i2c_match[] = {
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
BI_ABORT_IF(NE, BIND_I2C_BUS_ID, ASTRO_I2C_2),
BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, I2C_GOODIX_TOUCH_ADDR),
};
static const zx_bind_inst_t gpio_int_match[] = {
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
BI_MATCH_IF(EQ, BIND_GPIO_PIN, GPIO_TOUCH_INTERRUPT),
};
static const zx_bind_inst_t gpio_reset_match[] = {
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
BI_MATCH_IF(EQ, BIND_GPIO_PIN, GPIO_TOUCH_RESET),
};
static const device_fragment_part_t ft_i2c_fragment[] = {
{countof(ft_i2c_match), ft_i2c_match},
};
static const device_fragment_part_t goodix_i2c_fragment[] = {
{countof(goodix_i2c_match), goodix_i2c_match},
};
static const device_fragment_part_t gpio_int_fragment[] = {
{countof(gpio_int_match), gpio_int_match},
};
static const device_fragment_part_t gpio_reset_fragment[] = {
{countof(gpio_reset_match), gpio_reset_match},
};
static const device_fragment_t ft_fragments[] = {
{"i2c", countof(ft_i2c_fragment), ft_i2c_fragment},
{"gpio-int", countof(gpio_int_fragment), gpio_int_fragment},
{"gpio-reset", countof(gpio_reset_fragment), gpio_reset_fragment},
};
static const device_fragment_t goodix_fragments[] = {
{"i2c", countof(goodix_i2c_fragment), goodix_i2c_fragment},
{"gpio-int", countof(gpio_int_fragment), gpio_int_fragment},
{"gpio-reset", countof(gpio_reset_fragment), gpio_reset_fragment},
};
const zx_device_prop_t props[] = {
{BIND_PLATFORM_DEV_VID, 0, PDEV_VID_GENERIC},
{BIND_PLATFORM_DEV_PID, 0, PDEV_PID_ASTRO},
{BIND_PLATFORM_DEV_DID, 0, PDEV_DID_FOCALTOUCH},
};
然後使用 DdkAddComposite()
API 新增:
const composite_device_desc_t comp_desc = {
.props = props,
.props_count = std::size(props),
.fragments = ft3x27_touch_fragments,
.fragments_count = std::size(ft3x27_touch_fragments),
.primary_fragment = "i2c",
};
zx_status_t status = DdkAddComposite("ft3x27-touch", &comp_desc);
if (status != ZX_OK) {
zxlogf(ERROR, "%s(ft3x27): CompositeDeviceAdd failed: %d", __func__, status);
return status;
}
包含節點群組的複合驅動程式
使用節點群組時,節點表示法繫結規則可與 GPIO 接腳規則相符 並為 GPIO 接腳類型提供繫結屬性。這樣一來 複合型驅動程式庫,用於包含非主面板適用的繫結規則 保持開啟。
假設有 fuchsia.gpio 繫結程式庫:
library fuchsia.gpio;
extend uint fuchsia.BIND_PROTOCOL {
DEVICE = 20,
IMPL = 21,
};
enum FUNCTION {
TOUCH_INTERRUPT,
TOUCH_RESET,
};
節點群組可以定義如下:
node {
bind_rules {
fuchsia.BIND_FIDL_PROTOCOL == fuchsia.i2c.BIND_FIDL_PROTOCOL.DEVICE;
fuchsia.BIND_I2C_BUS_ID == fuchsia.i2c.BIND_I2C_BUS_ID.ASTRO_2;
fuchsia.BIND_I2C_ADDRESS == fuchsia.i2c.BIND_I2C_ADDRESS.FOCALTECH_TOUCH;
},
bind_properties {
fuchsia.BIND_FIDL_PROTOCOL: fuchsia.i2c.BIND_FIDL_PROTOCOL.DEVICE,
fuchsia.gpio.FUNCTION: fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH,
}
}
node {
bind_rules {
fuchsia.BIND_PROTOCOL == fuchsia.gpio.BIND_PROTOCOL.DEVICE;
fuchsia.BIND_GPIO_PIN == fuchsia.amlogic.platform.s905d3.GPIOZ_PIN_ID.PIN_6;
},
bind_properties {
fuchsia.BIND_PROTOCOL: fuchsia.gpio.BIND_PROTOCOL.DEVICE,
fuchsia.gpio.FUNCTION: fuchsia.gpio.FUNCTION.TOUCH_INTERRUPT,
fuchsia.gpio.BIND_PLATFORM_DEV_DID:
fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH,
}
}
node {
bind_rules {
fuchsia.BIND_PROTOCOL == fuchsia.gpio.BIND_PROTOCOL.DEVICE;
fuchsia.BIND_GPIO_PIN == fuchsia.amlogic.platform.s905d3.GPIOZ_PIN_ID.PIN_9;
},
bind_properties {
fuchsia.BIND_PROTOCOL: fuchsia.gpio.BIND_PROTOCOL.DEVICE,
fuchsia.gpio.FUNCTION: fuchsia.gpio.FUNCTION.TOUCH_RESET,
fuchsia.BIND_PLATFORM_DEV_DID:
fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH,
}
}
有了 driver2
程式庫 (DFv1 的 DDK),驅動程式庫程式碼就可以新增節點
群組:
const fdf::BindRule i2c_bind_rules[] = {
fdf::BindRule::Accept(
BIND_FIDL_PROTOCOL, bind_fuchsia_i2c::BIND_FIDL_PROTOCOL_DEVICE),
fdf::BindRule::Accept(
BIND_I2C_BUS_ID, bind_fuchsia_i2c::BIND_I2C_BUS_ID_ASTRO_2),
fdf::BindRule::Accept(
BIND_I2C_ADDRESS, bind_fuchsia_i2c::BIND_I2C_ADDRESS_FOCALTECH_TOUCH),
};
const fdf::NodeProperty i2c_bind_properties[] = {
fdf::MakeProperty(BIND_FIDL_PROTOCOL,
bind_fuchsia_i2c::BIND_FIDL_PROTOCOL_DEVICE),
fdf::MakeProperty(BIND_PLATFORM_DEV_DID,
bind_fuchsia_platform::BIND_PLATFORM_DEV_DID_FOCALTOUCH),
};
const fdf::BindRule gpio_interrupt_bind_rules[] = {
fdf::BindRule::Accept(
BIND_PROTOCOL, bind_fuchsia_gpio::BIND_PROTOCOL_DEVICE),
fdf::BindRule::Accept(
BIND_GPIO_PIN, bind_fuchsia_amlogic_platform_s905d2::GPIOZ_PIN_ID_PIN_4),
}
const fdf::NodeProperty gpio_interrupt_bind_properties[] = {
fdf::MakeProperty(BIND_PROTOCOL, bind_fuchsia_gpio::BIND_PROTOCOL_DEVICE),
fdf::MakeProperty(bind_fuchsia_gpio::FUNCTION,
bind_fuchsia_gpio::FUNCTION_TOUCH_INTERRUPT),
fdf::MakeProperty(BIND_PLATFORM_DEV_DID,
bind_fuchsia_platform::BIND_PLATFORM_DEV_DID_FOCALTOUCH),
};
const fdf::BindRule gpio_reset_bind_rules[] = {
fdf::BindRule::Accept(
BIND_PROTOCOL, bind_fuchsia_gpio::BIND_PROTOCOL_DEVICE),
fdf::BindRule::Accept(
BIND_GPIO_PIN, bind_fuchsia_amlogic_platform_s905d2::GPIOZ_PIN_ID_PIN_9),
};
const fdf::NodeProperty gpio_reset_bind_properties[] = {
fdf::MakeProperty(BIND_PROTOCOL, bind_fuchsia_gpio::BIND_PROTOCOL_DEVICE),
fdf::MakeProperty(bind_fuchsia_gpio::FUNCTION,
bind_fuchsia_gpio::FUNCTION_TOUCH_RESET),
fdf::MakeProperty(BIND_PLATFORM_DEV_DID,
bind_fuchsia_platform::BIND_PLATFORM_DEV_DID_FOCALTOUCH),
};
auto focaltech_touch_device =
fdf::NodeGroup(i2c_bind_rules, i2c_bind_properties)
.AddNodeRepresentation(gpio_interrupt_bind_rules,
gpio_interrupt_bind_properties)
.AddNodeRepresentation(gpio_reset_bind_rules, gpio_reset_bind_properties);
fdf::AddNodeGroup(node, focaltech_touch_device);
接著,需要更新 Focaltech 驅動程式庫複合繫結規則:
composite ft3x27_touch;
using fuchsia.amlogic.platform.s905d2;
using fuchsia.gpio;
using fuchsia.i2c;
using fuchsia.platform;
primary node "i2c" {
fuchsia.BIND_FIDL_PROTOCOL == fuchsia.i2c.BIND_FIDL_PROTOCOL.DEVICE;
fuchsia.BIND_PLATFORM_DEV_DID ==
fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH;
}
node "gpio-int" {
fuchsia.BIND_PROTOCOL == fuchsia.gpio.BIND_PROTOCOL.DEVICE;
fuchsia.gpio.GPIO_FUNCTION == fuchsia.gpio.GPIO_FUNCTION.TOUCH_INTERRUPT;
fuchsia.BIND_PLATFORM_DEV_DID ==
fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH;
}
node "gpio-reset" {
fuchsia.BIND_PROTOCOL == fuchsia.gpio.BIND_PROTOCOL.DEVICE;
fuchsia.gpio.GPIO_FUNCTION == fuchsia.gpio.GPIO_FUNCTION.TOUCH_RESET;
fuchsia.BIND_PLATFORM_DEV_DID ==
fuchsia.platform.BIND_PLATFORM_DEV_DID.FOCALTOUCH;
}
DFv2 複合驅動程式的變更
節點群組會取代 DFv2 複合驅動程式目前的機制。於 複合節點日後只能透過節點群組建立建立節點後 群組完整實作 DFv2,我們會將所有複合式驅動程式 並移除目前的機制
實作
這項變更將包含支援的節點群組至「fuchsia.driver.framework
」
FIDL API。驅動程式管理器和索引需要更新
處理及追蹤所有節點群組
如要支援選用節點,必須更新繫結編譯器,以支援
使用繫結語言的 optional
關鍵字,並將資訊編碼為
位元碼。
遷移至節點群組
由於所有複合資料都會透過節點群組建立,所有現有項目 DFv1 和 DFv2 中的複合元件必須在準備就緒後遷移至節點群組
在 DFv1 中,AddComposite()
的所有使用方式都將替換為
DDK 中的 AddNodeGroup()
函式呼叫。這包括將驅動程式庫遷移至
,然後使用複合型繫結規則來建立複合驅動程式庫,再以
AddNodeGroup()
。
在 DFv2 中,您必須為每個複合驅動程式庫建立相符的節點群組。
由於兩者都支援目前的複合驅動程式庫實作,因此可以 確保驅動程式庫索引與相符節點發生衝突。適用對象 執行個體,如果節點與複合式驅動程式庫或節點群組中的任一節點, 驅動程式庫索引可能只會傳回一個相符項目。避免這種情況的方法之一 系統會優先比對節點群組,而非複合驅動程式。
為避免發生迴歸問題,每個遷移的驅動程式庫都將經過手動驗證, 測試DFv1 的遷移作業並不困難,因此需要更多時間 驗證司機所需費用。
所有複合驅動程式都遷移至節點群組後,我們就能移除 目前的實作程序。
成效
這麼做並不會對效能產生實質影響,因為這與複合結構類似 DFv1 中的節點
人體工學
透過 FIDL 繫結直接建立節點群組並非人體工學。目的地:
我們將在此建立輔助程式庫
driver2
,用於定義繫結規則和屬性。
大部分的節點群組都是透過 DSL 定義,例如 ACPI 和裝置 。因此,打造非常符合人體工學的原則並不是首要之務 透過主機驅動程式中的程式碼寫入節點群組
回溯相容性
此版本必須與 DFv1 和 DFv2 相容。為瞭解決這個問題
實作 DFv1 的節點群組DFv1 驅動程式可透過以下方式新增節點群組:
DDK。所有 AddComposite()
呼叫都會遷移至節點群組。Compat 輔助程式
必須在 DFv1 和 DFv2 之間進行橋接。
安全性考量
其中一個問題在於節點群組是以動態方式定義 以靜態方式稽核 Jamboard 設定。您可以操控節點 您無須繫結至任何節點的拓撲
為瞭解決這個問題,主機驅動程式庫會是可新增節點群組的主機驅動程式。這個 可能會受到功能限制此外,我們日後會 將重要資料遷移至宣告式格式 (例如裝置樹狀結構和 ACPI) 以便稽核
隱私權注意事項
無
測試
系統會為此編寫整合測試和單元測試。
說明文件
我們也會更新複合裝置概念說明文件。此外, 建立節點群組時,可於編寫主面板驅動程式庫的教學課程中示範。
缺點、替代方案和未知
雖然 AddNodeGroup()
提供 AddComposite()
中的所有功能,但
仍可能出現缺漏或未能解決的應用情境。於
此外,開始將 AddComposite()
個案件遷移至節點群組時
可能還會找出更多極端情況
有一些較複雜的情況,例如 ACPI 匯流排會動態更新 逐一查看 ACPI 表格並加入複合資料。由於有許多 繫結至 ACPI 複合材料的驅動程式時,我們可能需要遷移多個 司機