GPIO 初始化

部分驅動程式需要使用靜態 GPIO 接腳或 PIN 碼, 特定原則在這類情況下,通常會希望保留 GPIO 確保輔助驅動程式的設定詳細資料 以及保持可攜性要做到這點 並包含初始化步驟清單至 GPIO 驅動程式庫。請見下方說明 舉例來說

在 Jamboard 驅動程式庫中設定 GPIO 中繼資料

舉例來說,假設 SDMMC 驅動程式庫需要使用 PIN 碼設定 特定替代功能與硬碟強度為此,主機板驅動程式 建立 fuchsia.hardware.gpioimpl.InitStep 物件清單,指定 要發出的 GPIO 通訊協定呼叫,以及用來呼叫的 GPIO 索引:

#include <fidl/fuchsia.hardware.gpioimpl/cpp/wire.h>

// Helper lambda to simplify the following code.
auto sdmmc_gpio = [&](uint64_t alt_function, uint64_t drive_strength_ua) {
  return fuchsia_hardware_gpioimpl::wire::InitOptions::Builder(arena)
      .alt_function(alt_function)
      .drive_strength_ua(drive_strength_ua)
      .Build();
};

const fuchsia_hardware_gpioimpl::wire::InitStep init_steps[] = {
    {SDMMC_GPIO_0, sdmmc_gpio(SDMMC_GPIO_0_ALT_FUNCTION, 4000)},
    {SDMMC_GPIO_1, sdmmc_gpio(SDMMC_GPIO_1_ALT_FUNCTION, 4000)},
    {SDMMC_GPIO_2, sdmmc_gpio(SDMMC_GPIO_2_ALT_FUNCTION, 4000)},
    {SDMMC_GPIO_3, sdmmc_gpio(SDMMC_GPIO_3_ALT_FUNCTION, 4000)},
    {SDMMC_GPIO_4, sdmmc_gpio(SDMMC_GPIO_4_ALT_FUNCTION, 4000)},
    {SDMMC_GPIO_5, sdmmc_gpio(SDMMC_GPIO_5_ALT_FUNCTION, 4000)},
};

接著,這份清單會以中繼資料的形式提供給 GPIO 驅動程式庫:


fuchsia_hardware_gpioimpl::wire::InitMetadata metadata;
metadata.steps = fidl::VectorView<fuchsia_hardware_gpioimpl::wire::InitStep>::FromExternal(
    init_steps, std::size(init_steps));

fit::result encoded = fidl::Persist(metadata);
if (!encoded.is_ok()) {
  return encoded.error_value().status();
}

const std::vector<fpbus::Metadata> gpio_metadata{
    {{
        .type = DEVICE_METADATA_GPIO_INIT_STEPS,
        .data = std::move(encoded.value()),
    }},
    // Other metadata goes here.
};

const fpbus::Node gpio_dev = []() {
  fpbus::Node dev = {};
  dev.name() = "gpio";
  dev.vid() = PDEV_VID_SOME_VENDOR;
  dev.pid() = PDEV_PID_SOME_PRODUCT;
  dev.did() = PDEV_DID_SOME_GPIO_DEVICE;
  dev.mmio() = gpio_mmios;
  dev.irq() = gpio_irqs;
  dev.metadata() = gpio_metadata;
  return dev;
}();

// Add the node here.

使用繫結規則建立 GPIO 設定的依附元件

現在 GPIO 驅動程式庫已正確設定這些針腳,SDMMC 驅動程式庫 必須在繫結前依附於此設定。這是 方法是在裝置的 SDMMC 裝置上新增其他片段 驅動程式庫繫結檔案:

using fuchsia.gpio;

// Other nodes go here.

node "gpio-init" {
  fuchsia.BIND_INIT_STEP == fuchsia.gpio.BIND_INIT_STEP.GPIO;
  fuchsia.BIND_GPIO_CONTROLLER = 1;
}

之後 GPIO 驅動程式會新增 fuchsia.gpio.BIND_INIT_STEP.GPIO 裝置 就完成了初始化步驟不限人數 與這部裝置繫結,確保先前已設定 GPIO 。

GPIO 驅動程式庫如何處理設定錯誤

當 GPIO 驅動程式庫在處理初始化步驟時發生錯誤, 它會繼續設定其餘的 GPIO,但不會新增 init 裝置。 這是為了確保盡可能多組圖釘進入已知狀態, 駕駛不會嘗試用可能導致故障的 PIN 碼跑步 設定錯誤。同樣地,如果沒有 GPIO 驅動程式庫,則不會新增 init 裝置 是否可剖析初始化中繼資料。

在下列兩種情況中,建議使用 GPIO init 步驟:

  • 驅動程式需要靜態主機或平台專屬的 GPIO 設定。

向上/下拉、Alt 函式和硬碟強度設定通常 使用 GPIO init 並以 GPIO init 控制面板 最好使用驅動程式庫。在下列情況下,也建議您設定 GPIO 輸出值: 在所有主機板上的值皆不相同 (或非必要)。

  • 多個驅動程式依附單一 GPIO 的靜態設定。

如果有多個驅動程式仰賴單一 GPIO 的靜態設定, 應使用 GPIO init 來進行。這樣可以避免許多駕駛人 不得對單一 GPIO 發出可能發生衝突的呼叫

GPIO init 步驟不應用於任何將由 並在執行階段使用驅動程式庫

GPIO 初始化選項

如需初始化選項的完整清單和相關說明,請參閱 fuchsia.hardware.pinimpl FIDL 規格。