應使用註冊驅動程式的註冊, 可讓多個駕駛人存取。
概念
驅動程式通常會透過註冊式介面與硬體通訊。 概念上,暫存器是 8/16/32/64 位元的群組,可讀取或 能夠透過位址空間編寫您可以透過 CPU 的 記憶體位址空間,而 I2C 暫存器則透過 I2C 匯流排存取。
大部分硬體僅支援不可分割的暫存器寫入。因此,需要
若要變更暫存器的某些部分,必須透過讀取/修改/寫入來變更
作業。例如,假設要變更 32 位元暫存器,
0 至 1 位元和 0
之間,您需要讀取該暫存器的全部 32 位元,
說 0xFFFFFFFF
,然後寫回該註冊 0xFFFFFFFC
。
同步處理
讀取/修改/寫入作業可能造成資料競爭。 傳統交易範例「提款 $10 美元,銀行帳戶」為 這就等同於讀取/修改/寫入作業請參閱「資料競爭」: 請參閱「範例」一節中的具體說明。
註冊者為「專屬」時駕駛人 ,將其存取權同步到暫存器,以避免資料競爭。( 儘管風險仍然存在,但這不在 註冊驅動程式庫)。
當註冊者「共用」時可讓多位駕駛人存取 (也可以存取) 協調事件工作暫存器驅動程式庫可執行此操作 所有驅動程式庫只需存取不連貫的子集 。全球協調人員會 讀取/寫入暫存器之間的同步處理作業。
隔離
暫存器驅動程式庫不僅藉由提供同步處理機制來阻止賽跑 但也能區隔位元欄位暫存器的驅動程式庫分割 註冊多項資源,並確保每位驅動程式都只執行單一驅動程式 就能存取那些部分駕駛人可能不會意外讀取或寫入 但其實不然
營運理論
在桌遊驅動程式中, 由多個驅動程式存取時,系統會宣告 所有要公開的 Pod註冊驅動程式庫會為每個裝置建立裝置 缺少部分符記想要存取這些位元欄位需求的驅動程式 繫結至對應的裝置。
在註冊驅動程式庫中,系統會使用各暫存器的鎖定來確保 且只能讀取/寫入一次暫存器。Google Cloud 的介面 註冊驅動程式庫由 registers-util.fidl 定義。
使用方法
目前只有重設註冊是唯一的暫存器 改用註冊驅動程式庫的容器。這個部分會使用 做為如何使用暫存器驅動程式庫的範例
董事會驅動程式庫變更
中繼資料格式是在 metadata.fidl 宣告。
在主機板驅動程式庫 (即 nelson-registers) 中,將 。
a. MMIO
確認註冊驅動程式庫可存取 MMIO。如果不是 新增 MMIO 和相應的 MMIO 索引:
enum MmioMetadataIdx { kResetMmio, kMmioCount, }; static const std::vector<fpbus::Mmio> registers_mmios{ { { .base = A311D_RESET_BASE, .length = A311D_RESET_LENGTH, }, }, };
請注意,
MmioMetadataIndex
必須與 MMIO 的registers_mmios
中的索引。b. 宣告 Bitfields
RegistersMetadataToFidl
輔助工具 函式可用於宣告 Bitfields:auto metadata_bytes = fidl_metadata::registers::RegistersMetadataToFidl<uint32_t>(kRegisters); if (metadata_bytes.is_error()) { zxlogf(ERROR, "%s: Failed to FIDL encode registers metadata %s\n", __func__, metadata_bytes.status_string()); return metadata_bytes.error_value(); } const std::vector<fpbus::Metadata> registers_metadata{ { { .type = DEVICE_METADATA_REGISTERS, .data = metadata_bytes.value(), }, }, };
其中 Bitfields 已在
kRegisters
欄位中定義:static const fidl_metadata::registers::Register<uint32_t> kRegisters[]{ { .bind_id = aml_registers::REGISTER_USB_PHY_V2_RESET, .mmio_id = kResetMmio, .masks = { { .value = aml_registers::USB_RESET1_REGISTER_UNKNOWN_1_MASK | aml_registers::USB_RESET1_REGISTER_UNKNOWN_2_MASK, .mmio_offset = A311D_RESET1_REGISTER, }, { .value = aml_registers::USB_RESET1_LEVEL_MASK, .mmio_offset = A311D_RESET1_LEVEL, }, }, }, ... };
bind_id
:每個位元欄位定義的專屬 ID, 繫結期間才能識別容器mmio_id
:與這個位元欄位的 MMIO 相對應的 ID 參照。masks
:描述特定位元欄位的遮罩清單。 應能透過此註冊裝置存取。value
:您可以使用1
存取的位元遮罩 表示可存取,且0
無法存取。舉例來說 32 位元暫存器,位元遮罩可以是0xFFFF0000
,表示 就可以透過這個伺服器 註冊裝置,低階 16 版本則不需要。mmio_offset
:從 MMIO 開始的起始偏移 透過mmio_id
來識別。count
:這個位元欄位遮罩的註冊位址數量 適用於後續mmio_offset
。預設為1
。overlap_check_on
:如果為true
,註冊驅動程式庫會 並確定這些位元欄位並未與任何其他 已定義 Bitfields否則系統會略過檢查。預設值 至true
。
註冊驅動程式庫會建立提供 registers-util.fidl 的裝置 具有繫結屬性:
{:.devsite-disable-click-to-copy} bind_fuchsia_register::NAME == bind_id
繫結至註冊驅動程式庫
想要存取這些 Bit 欄位的驅動程式接著必須繫結至 。
使用註冊驅動程式庫介面
成功連線至註冊裝置後,例如
fidl::WireSyncClient<fuchsia_hardware_registers::Device> register
, 您可以根據 FIDL 呼叫對應的 FIDL 讀取/寫入方法 registers-util.fidl 中定義的介面。 例如,如果是 32 位元暫存器auto result = reset_register_->WriteRegister32(RESET1_LEVEL_OFFSET, aml_registers::USB_RESET1_LEVEL_MASK, aml_registers::USB_RESET1_LEVEL_MASK); if ((result.status() != ZX_OK) || result->is_error()) { zxlogf(ERROR, "Write failed\n"); return ZX_ERR_INTERNAL; }
歡迎體驗獨立的同步註冊裝置!
範例
資料競爭
假設我們的暫存器同時由驅動程式庫 A 和驅動程式庫 B 存取。
現在驅動程式庫 A 想要將 b01
寫入暫存器和驅動程式庫的位元 0-1 中
B 想要將 b001
寫入暫存器的 8-10 位元。取決於時間
驅動程式庫 A 可能會讀取暫存器的原始值,例如:0xFFFFFFFF
,
驅動程式庫 B 也可能會讀取相同的值。驅動程式 A 接著寫入位元 0-1
並放入記憶體 0xFFFFFFFD
中。接著驅動程式 B 會寫入記憶體
0xFFFFF9FF
。在事件序列中,暫存器現在會保留此值
0xFFFFF9FF
,驅動程式庫 B 上次寫入。不過下次
驅動程式庫 A 讀取了此暫存器的位元 0-1,但無法取得
這個值會和之前寫入時一樣
AMLogic SoC
本節提供一些範例,說明暫存器驅動程式庫應的位置 。註冊驅動程式庫時絕對應使用 多個驅動程式之間的同步處理作業,但不一定 僅適用於隔離資源請注意,此處僅列舉部分例子,並未包含所有可能情況。 AMLogic SoC 中的共用暫存器清單。
重設暫存器
AMLogic SoC 擁有各種硬體設備的重設功能
而且程式只集中在少數 32 位元暫存器中具體做法為
S905D3 資料表 6-186 中的 RESET1_REGISTER
。例如,USB 重設是
由位元 2 和 SD_EMMC 由位元 12-14 控制。硬體設計團隊
我們會將「RESET1_REGISTER
」分享給多名司機,包括 EMMC
以及 USB 驅動程式庫
如要瞭解重設的 Jamboard 檔案變更,請參閱 nelson-registers。
暫存器和 nelson-usb - 用於新增重設裝置數量的 aml_usb_phy
部裝置
註冊片段。aml-usb-phy 的 AmlUsbPhy::InitPhy()
用途
要寫入重設暫存器的 FIDL 用戶端。
電源暫存器
與上述重設暫存器類似,AO_RTI_GEN_PWR_SLEEP0
(S905D3 表格 6-17) 和 AO_RTI_GEN_PWR_ISO0
(S905D3 資料表)
6 到 18) 由多個驅動程式共用,包括螢幕、USB 與機器學習,
由註冊驅動程式庫管理,因為這類檔案可以寫入
協調程序。這項遷移作業正在進行中,
另一方面,雖然 AO_RTI_GEN_PWR_ACK0
(S905D3 表 6-19)
由多個驅動程式 (PCIE、USB、顯示器等) 共用,處於唯讀狀態。
您可以同時存取這個暫存器中的資料,不需任何競爭風險。
因此不需要使用暫存器驅動程式庫進行同步處理。如果
我們仍可能會使用暫存器驅動程式庫來隔離資源。