GPIO、I2C、SPI へのユーザー モード アクセスの有効化Enable usermode access to GPIO, I2C, and SPI

Windows 10 には、GPIO、I2C、SPI、UART にユーザー モードから直接アクセスするための新しい API が含まれています。Windows 10 contains new APIs for accessing GPIO, I2C, SPI, and UART directly from usermode. Raspberry Pi 2 のような開発ボードは、特定のアプリケーションに対処するためにユーザーがカスタム回路を使って基本計算モジュールを拡張できるようにする、これらの接続のサブセットを公開しています。Development boards like Raspberry Pi 2 expose a subset of these connections which enable users to extend a base compute module with custom circuitry to address a particular application. 通常、これらの低レベル バスはその他の重要なオンボード機能と共有され、GPIO ピンのサブセットとバスのみがヘッダーで公開されます。These low level buses are usually shared with other critical onboard functions, with only a subset of GPIO pins and buses exposed on headers. システムの安定性を維持するために、どのピンとバスの変更が安全かをユーザー モード アプリケーションで指定する必要があります。To preserve system stability, it is necessary to specify which pins and buses are safe for modification by usermode applications.

このドキュメントでは、ACPI でこの構成を指定する方法を説明し、構成が正しく指定されていることを検証するためのツールを提供します。This document describes how to specify this configuration in ACPI and provides tools to validate that the configuration was specified correctly.

重要

このドキュメントの対象者は、UEFI と ACPI の開発者です。The audience for this document is UEFI and ACPI developers. ACPI、ASL 作成、SpbCx/GpioClx についてある程度の知識があることを前提としています。Some familiarity with ACPI, ASL authoring, and SpbCx/GpioClx is assumed.

Windows での低レベル バスへのユーザー モード アクセスは、既存の GpioClx および SpbCx フレームワークを通じて組み込まれています。Usermode access to low level buses on Windows is plumbed through the existing GpioClx and SpbCx frameworks. Windows 10 IoT Core と Windows Enterprise で使用可能な RhProxy という新しいドライバーが、GpioClx リソースと SpbCx リソースをユーザー モードに公開します。A new driver called RhProxy, available on Windows IoT Core and Windows Enterprise, exposes GpioClx and SpbCx resources to usermode. API を有効にするには、ユーザー モードに公開する GPIO リソースと SPB リソースのそれぞれで、ACPI テーブル内で rhproxy 用のデバイス ノードが宣言されている必要があります。To enable the APIs, a device node for rhproxy must be declared in your ACPI tables with each of the GPIO and SPB resources that should be exposed to usermode. このドキュメントでは、ASL の作成と検証について説明します。This document walks through authoring and verifying the ASL.

ASL の例ASL by example

Raspberry Pi 2 での rhproxy デバイス ノードの宣言について説明します。Let’s walk through the rhproxy device node declaration on Raspberry Pi 2. 最初に、ACPI デバイスの宣言を作成、 \_SB スコープ。First, create the ACPI device declaration in the \_SB scope.

Device(RHPX)
{
    Name(_HID, "MSFT8000")
    Name(_CID, "MSFT8000")
    Name(_UID, 1)
}
  • _HID – ハードウェア ID です。ベンダー固有のハードウェア ID に設定します。_HID – Hardware Id. Set this to a vendor-specific hardware ID.
  • _CID – 互換性 ID です。“MSFT8000” にする必要があります。_CID – Compatible Id. Must be “MSFT8000”.
  • _UID – 一意の ID です。1 に設定します。_UID – Unique Id. Set to 1.

次に、ユーザー モードに公開する GPIO リソースと SPB リソースをそれぞれ宣言します。Next we declare each of the GPIO and SPB resources that should be exposed to usermode. プロパティとリソースを関連付けるためにリソース インデックスが使われるため、リソースが宣言される順序は重要です。The order in which resources are declared is important because resource indexes are used to associate properties with resources. 複数の I2C または SPI バスが公開されている場合は、最初に宣言されているバスがその種類のバスの '既定' と見なされ、Windows.Devices.I2c.I2cController および Windows.Devices.Spi.SpiControllerGetDefaultAsync() メソッドによって返されるインスタンスになります。If there are multiple I2C or SPI busses exposed, the first declared bus is considered the ‘default’ bus for that type, and will be the instance returned by the GetDefaultAsync() methods of Windows.Devices.I2c.I2cController and Windows.Devices.Spi.SpiController.

SPISPI

Raspberry Pi には 2 つの公開されている SPI バスがあります。Raspberry Pi has two exposed SPI buses. SPI0 には 2 つのハードウェア チップ選択線があり、SPI1 には 1 つのハードウェア チップ選択線があります。SPI0 has two hardware chip select lines and SPI1 has one hardware chip select line. 各バスの各チップ選択線に 1 つの SPISerialBus() リソース宣言が必要です。One SPISerialBus() resource declaration is required for each chip select line for each bus. 次の 2 つの SPISerialBus リソース宣言は、SPI0 の 2 つのチップ選択線用です。The following two SPISerialBus resource declarations are for the two chip select lines on SPI0. DeviceSelection フィールドには、ドライバーがハードウェア チップ選択線識別子として解釈する一意の値が含まれます。The DeviceSelection field contains a unique value which the driver interprets as a hardware chip select line identifier. DeviceSelection フィールドに入れる正確な値は、ACPI 接続記述子のこのフィールドをドライバーがどのように解釈するかによって異なります。The exact value that you put in the DeviceSelection field depends on how your driver interprets this field of the ACPI connection descriptor.

// Index 0
SPISerialBus(              // SCKL - GPIO 11 - Pin 23
                           // MOSI - GPIO 10 - Pin 19
                           // MISO - GPIO 9  - Pin 21
                           // CE0  - GPIO 8  - Pin 24
    0,                     // Device selection (CE0)
    PolarityLow,           // Device selection polarity
    FourWireMode,          // wiremode
    0,                     // databit len: placeholder
    ControllerInitiated,   // slave mode
    0,                     // connection speed: placeholder
    ClockPolarityLow,      // clock polarity: placeholder
    ClockPhaseFirst,       // clock phase: placeholder
    "\\_SB.SPI0",          // ResourceSource: SPI bus controller name
    0,                     // ResourceSourceIndex
                           // Resource usage
    )                      // Vendor Data

// Index 1
SPISerialBus(              // SCKL - GPIO 11 - Pin 23
                           // MOSI - GPIO 10 - Pin 19
                           // MISO - GPIO 9  - Pin 21
                           // CE1  - GPIO 7  - Pin 26
    1,                     // Device selection (CE1)
    PolarityLow,           // Device selection polarity
    FourWireMode,          // wiremode
    0,                     // databit len: placeholder
    ControllerInitiated,   // slave mode
    0,                     // connection speed: placeholder
    ClockPolarityLow,      // clock polarity: placeholder
    ClockPhaseFirst,       // clock phase: placeholder
    "\\_SB.SPI0",          // ResourceSource: SPI bus controller name
    0,                     // ResourceSourceIndex
                           // Resource usage
    )                      // Vendor Data

ソフトウェアはどのようにしてこれらの 2 つのリソースを同じバスに関連付ける必要があることを把握するのでしょうか。How does software know that these two resources should be associated with the same bus? バスのフレンドリ名とリソース インデックスの間のマッピングが DSD で指定されます。The mapping between bus friendly name and resource index is specified in the DSD:

Package(2) { "bus-SPI-SPI0", Package() { 0, 1 }},

これにより、2 つのチップ選択線 (リソース インデックス 0 および 1) を持つ “SPI0” という名前のバスが作成されます。This creates a bus named “SPI0” with two chip select lines – resource indexes 0 and 1. SPI バスの機能を宣言するには、さらにいくつかのプロパティが必要です。Several more properties are required to declare the capabilities of the SPI bus.

Package(2) { "SPI0-MinClockInHz", 7629 },
Package(2) { "SPI0-MaxClockInHz", 125000000 },

MinClockInHz および MaxClockInHz プロパティは、コントローラーでサポートされる最小および最大のクロック速度を指定します。The MinClockInHz and MaxClockInHz properties specify the minimum and maximum clock speeds that are supported by the controller. API はこの範囲外の値をユーザーが指定できないようにします。The API will prevent users from specifying values outside this range. クロック速度は接続記述子の _SPE フィールドの SPB ドライバーに渡されます (ACPI セクション 6.4.3.8.2.2)。The clock speed is passed to your SPB driver in the _SPE field of the connection descriptor (ACPI section 6.4.3.8.2.2).

Package(2) { "SPI0-SupportedDataBitLengths", Package() { 8 }},

SupportedDataBitLengths プロパティには、コントローラーでサポートされるデータのビット長が一覧表示されます。The SupportedDataBitLengths property lists the data bit lengths supported by the controller. コンマ区切りの一覧で複数の値を指定することができます。Multiple values can be specified in a comma-separated list. API はこの一覧以外の値をユーザーが指定できないようにします。The API will prevent users from specifying values outside this list. データのビット長は接続記述子の _LEN フィールドの SPB ドライバーに渡されます (ACPI セクション 6.4.3.8.2.2)。The data bit length is passed to your SPB driver in the _LEN field of the connection descriptor (ACPI section 6.4.3.8.2.2).

これらのリソース宣言は “テンプレート” として考えることができます。You can think of these resource declarations as “templates.” システムの起動時に固定されるフィールドと、実行時に動的に指定されるフィールドがあります。Some of the fields are fixed at system boot while others are specified dynamically at runtime. SPISerialBus 記述子の次のフィールドは固定されています。The following fields of the SPISerialBus descriptor are fixed:

  • DeviceSelectionDeviceSelection
  • DeviceSelectionPolarityDeviceSelectionPolarity
  • WireModeWireMode
  • SlaveModeSlaveMode
  • ResourceSourceResourceSource

次のフィールドは、実行時にユーザーによって指定される値のプレースホルダーです。The following fields are placeholders for values specified by the user at runtime:

  • DataBitLengthDataBitLength
  • ConnectionSpeedConnectionSpeed
  • ClockPolarityClockPolarity
  • ClockPhaseClockPhase

SPI1 には単一のチップ選択行のみが含まれているため、単一の SPISerialBus() リソースが宣言されます。Since SPI1 contains only a single chip select line, a single SPISerialBus() resource is declared:

// Index 2
SPISerialBus(              // SCKL - GPIO 21 - Pin 40
                           // MOSI - GPIO 20 - Pin 38
                           // MISO - GPIO 19 - Pin 35
                           // CE1  - GPIO 17 - Pin 11
    1,                     // Device selection (CE1)
    PolarityLow,           // Device selection polarity
    FourWireMode,          // wiremode
    0,                     // databit len: placeholder
    ControllerInitiated,   // slave mode
    0,                     // connection speed: placeholder
    ClockPolarityLow,      // clock polarity: placeholder
    ClockPhaseFirst,       // clock phase: placeholder
    "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
    0,                     // ResourceSourceIndex
                           // Resource usage
    )                      // Vendor Data

付随する必須のフレンドリ名宣言は DSD で指定され、このリソース宣言のインデックスを参照します。The accompanying friendly name declaration – which is required – is specified in the DSD and refers to the index of this resource declaration.

Package(2) { "bus-SPI-SPI1", Package() { 2 }},

これにより “SPI1” という名前のバスが作成され、リソース インデックス 2 に関連付けられます。This creates a bus named “SPI1” and associates it with resource index 2.

SPI ドライバーの要件SPI Driver Requirements

  • SpbCx を使うか、SpbCx と互換性がある必要がありますMust use SpbCx or be SpbCx-compatible
  • MITT SPI テストに合格している必要がありますMust have passed the MITT SPI Tests
  • 4 Mhz のクロック周波数をサポートしている必要がありますMust support 4Mhz clock speed
  • 8 ビットのデータ長をサポートしている必要がありますMust support 8-bit data length
  • すべての SPI モードをサポートする必要があります。0, 1, 2, 3Must support all SPI Modes: 0, 1, 2, 3

I2CI2C

次に、I2C リソースを宣言します。Next, we declare the I2C resources. Raspberry Pi はピン 3 および 5 で単一の I2C バスを公開しています。Raspberry Pi exposes a single I2C bus on pins 3 and 5.

// Index 3
I2CSerialBus(              // Pin 3 (GPIO2, SDA1), 5 (GPIO3, SCL1)
    0xFFFF,                // SlaveAddress: placeholder
    ,                      // SlaveMode: default to ControllerInitiated
    0,                     // ConnectionSpeed: placeholder
    ,                      // Addressing Mode: placeholder
    "\\_SB.I2C1",          // ResourceSource: I2C bus controller name
    ,
    ,
    )                      // VendorData

付随する必須のフレンドリ名宣言は DSD で指定されます。The accompanying friendly name declaration – which is required – is specified in the DSD:

Package(2) { "bus-I2C-I2C1", Package() { 3 }},

これは、上記の説明で宣言した I2CSerialBus() リソースのインデックスであるリソース インデックス 3 を参照する、フレンドリ名 “I2C1” の I2C バスを宣言します。This declares an I2C bus with friendly name “I2C1” that refers to resource index 3, which is the index of the I2CSerialBus() resource that we declared above.

I2CSerialBus() 記述子の次のフィールドは固定されています。The following fields of the I2CSerialBus() descriptor are fixed:

  • SlaveModeSlaveMode
  • ResourceSourceResourceSource

次のフィールドは、実行時にユーザーによって指定される値のプレースホルダーです。The following fields are placeholders for values specified by the user at runtime.

  • SlaveAddressSlaveAddress
  • ConnectionSpeedConnectionSpeed
  • AddressingModeAddressingMode

I2C ドライバーの要件I2C Driver Requirements

  • SpbCx を使うか、SpbCx と互換性がある必要がありますMust use SpbCx or be SpbCx-compatible
  • MITT I2C テストに合格している必要がありますMust have passed the MITT I2C Tests
  • 7 ビットのアドレス指定をサポートしている必要がありますMust support 7-bit addressing
  • 100 kHz のクロック周波数をサポートしている必要がありますMust support 100kHz clock speed
  • 400 kHz のクロック周波数をサポートしている必要がありますMust support 400kHz clock speed

GPIOGPIO

次に、ユーザー モードに公開されるすべての GPIO ピンを宣言します。Next, we declare all the GPIO pins that are exposed to usermode. どのピンを公開するかを判断するために、次のガイダンスを提供しています。We offer the following guidance in deciding which pins to expose:

  • 公開されるヘッダーのすべてのピンを宣言します。Declare all pins on exposed headers.
  • ボタンや LED などの役立つオンボード機能に接続されているピンを宣言します。Declare pins that are connected to useful onboard functions like buttons and LEDs.
  • システム機能のために予約されているピン、または何にも接続されていないピンは宣言しません。Do not declare pins that are reserved for system functions or are not connected to anything.

ASL の次のブロックでは、GPIO4 と GPIO5 の 2 つのピンが宣言されます。The following block of ASL declares two pins – GPIO4 and GPIO5. 簡潔にするために、その他のピンはここでは示しません。The other pins are not shown here for brevity. 付録 C には、GPIO リソースを生成するために使うことができるサンプル powershell スクリプトが含まれています。Appendix C contains a sample powershell script which can be used to generate the GPIO resources.

// Index 4 – GPIO 4
GpioIO(Shared, PullUp, , , , “\\_SB.GPI0”, , , , ) { 4 }
GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, “\\_SB.GPI0”,) { 4 }

// Index 6 – GPIO 5
GpioIO(Shared, PullUp, , , , “\\_SB.GPI0”, , , , ) { 5 }
GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, “\\_SB.GPI0”,) { 5 }

GPIO ピンを宣言するときは、次の要件を順守する必要があります。The following requirements must be observed when declaring GPIO pins:

  • メモリ マップ GPIO コントローラーのみがサポートされています。Only memory mapped GPIO controllers are supported. I2C/SPI 経由で接続された GPIO コントローラーはサポートされていません。GPIO controllers interfaced over I2C/SPI are not supported. CLIENT_QueryControllerBasicInformation コールバックへの応答で CLIENT_CONTROLLER_BASIC_INFORMATION 構造に MemoryMappedController フラグを設定する場合、コントローラー ドライバーはメモリ マップ コントローラーです。The controller driver is a memory mapped controller if it sets the MemoryMappedController flag in the CLIENT_CONTROLLER_BASIC_INFORMATION structure in response to the CLIENT_QueryControllerBasicInformation callback.
  • 各ピンに GpioIO リソースと GpioInt リソースの両方が必要です。Each pin requires both a GpioIO and a GpioInt resource. GpioInt リソースは GpioIO リソースの直後に続き、同じピン番号を参照する必要があります。The GpioInt resource must immediately follow the GpioIO resource and must refer to the same pin number.
  • GPIO リソースはピン番号の昇順で並べる必要があります。GPIO resources must be ordered by increasing pin number.
  • 各 GpioIO リソースと GpioInt リソースには、ピン一覧に正確に 1 つのピン番号を含める必要があります。Each GpioIO and GpioInt resource must contain exactly one pin number in the pin list.
  • 両方の記述子の ShareType フィールドが Shared である必要がありますThe ShareType field of both descriptors must be Shared
  • GpioInt 記述子の EdgeLevel フィールドが Edge である必要がありますThe EdgeLevel field of the GpioInt descriptor must be Edge
  • GpioInt 記述子の ActiveLevel フィールドが ActiveBoth である必要がありますThe ActiveLevel field of the GpioInt descriptor must be ActiveBoth
  • PinConfig フィールドThe PinConfig field
    • GpioIO 記述子と GpioInt 記述子の両方で同じである必要がありますMust be the same in both the GpioIO and GpioInt descriptors
    • PullUp、PullDown、PullNone のいずれかである必要があります。Must be one of PullUp, PullDown, or PullNone. PullDefault は指定できません。It cannot be PullDefault.
    • プル構成がピンの電源投入時の状態と一致する必要があります。The pull configuration must match the power-on state of the pin. ピンを電源投入時の状態から指定されたプル モードにしてもピンの状態が変更されないようにする必要があります。Putting the pin in the specified pull mode from power-on state must not change the state of the pin. たとえば、ピンでプル アップを使うようにデータシートで指定されている場合には、PinConfig を PullUp に指定する必要があります。For example, if the datasheet specifies that the pin comes up with a pull up, specify PinConfig as PullUp.

ファームウェア、UEFI、ドライバーの初期化コードが起動中の電源投入時の状態からピンの状態を変更しないようにする必要があります。Firmware, UEFI, and driver initialization code should not change the state of a pin from its power-on state during boot. ユーザーのみがピンに何が接続されているかを把握しているため、どの状態遷移が安全かが分かります。Only the user knows what’s attached to a pin and therefore which state transitions are safe. ピンと正しく接続されるハードウェアをユーザーが設計できるように、各ピンの電源投入時の状態を文書化する必要があります。The power-on state of each pin must be documented so that users can design hardware that correctly interfaces with a pin. 起動中にピンの状態が予期せず変更されないようにする必要があります。A pin must not change state unexpectedly during boot.

サポートされるドライバー モデルSupported Drive Modes

GPIO コントローラーで高インピーダンス入力と CMOS 出力に加えて組み込みのプル アップおよびプル ダウン抵抗がサポートされている場合は、オプションの SupportedDriveModes プロパティを使って指定する必要があります。If your GPIO controller supports built-in pull up and pull down resistors in addition to high impedance input and CMOS output, you must specify this with the optional SupportedDriveModes property.

Package (2) { “GPIO-SupportedDriveModes”, 0xf },

SupportedDriveModes プロパティは、GPIO コントローラーによってどのドライブ モードがサポートされるかを示します。The SupportedDriveModes property indicates which drive modes are supported by the GPIO controller. 上記の例では、次のドライブ モードがすべてサポートされます。In the example above, all of the following drive modes are supported. このプロパティは、次の値のビットマスクです。The property is a bitmask of the following values:

フラグ値Flag Value ドライブ モードDrive Mode 説明Description
0x10x1 InputHighImpedanceInputHighImpedance ピンが高インピーダンス入力をサポートします。ACPI の “PullNone” 値に対応します。The pin supports high impedance input, which corresponds to the “PullNone” value in ACPI.
0x20x2 InputPullUpInputPullUp ピンが組み込みのプル アップ抵抗をサポートします。ACPI の “PullUp” 値に対応します。The pin supports a built-in pull-up resistor, which corresponds to the “PullUp” value in ACPI.
0x40x4 InputPullDownInputPullDown ピンが組み込みのプル ダウン抵抗をサポートします。ACPI の “PullDown” 値に対応します。The pin supports a built-in pull-down resistor, which corresponds to the “PullDown” value in ACPI.
0x80x8 OutputCmosOutputCmos ピンが (オープン ドレインとは対照的に) ストロング ハイとストロング ローの両方の生成をサポートします。The pin supports generating both strong highs and strong lows (as opposed to open drain).

InputHighImpedance と OutputCmos はほぼすべての GPIO コントローラーでサポートされています。InputHighImpedance and OutputCmos are supported by almost all GPIO controllers. SupportedDriveModes プロパティが指定されていない場合は、既定になります。If the SupportedDriveModes property is not specified, this is the default.

GPIO 信号が公開されているヘッダーに到達する前にレベル シフターを通過する場合は、ドライブ モードが外部ヘッダーで監視可能でない場合でも、SOC によってサポートされているドライブ モードを宣言します。If a GPIO signal goes through a level shifter before reaching an exposed header, declare the drive modes supported by the SOC, even if the drive mode would not be observable on the external header. たとえば、ピンを抵抗プル アップを備えたオープン ドレインとして表す双方向レベル シフターをピンが通過する場合は、ピンが高インピーダンス入力として構成されている場合でも、公開されたヘッダーで高インピーダンス状態は観測されません。For example, if a pin goes through a bidirectional level shifter that makes a pin appear as open drain with resistive pull up, you will never observe a high impedance state on the exposed header even if the pin is configured as a high impedance input. この場合も、ピンが高インピーダンス入力をサポートすることを宣言する必要があります。You should still declare that the pin supports high impedance input.

ピンの番号付けPin Numbering

Windows は、2 つのピンの番号付けスキームをサポートしています。Windows supports two pin numbering schemes:

  • 連番のピンの番号付け: 0、1、2 ... のように、公開されているピンの数までの番号がユーザーに表示されます。Sequential Pin Numbering – Users see numbers like 0, 1, 2... up to the number of exposed pins. 0 は ASL で宣言されている最初の GpioIo リソース、1 は ASL で宣言されている 2 番目の GpioIo リソースなどのようになります。0 is the first GpioIo resource declared in ASL, 1 is the second GpioIo resource declared in ASL, and so on.
  • ネイティブの Pin 番号 – 5, 12, 13、GpioIo 記述子、例: 4 つの pin 番号が指定されたユーザーに表示しています.Native Pin Numbering – Users see the pin numbers specified in GpioIo descriptors, e.g. 4, 5, 12, 13, ...
Package (2) { “GPIO-UseDescriptorPinNumbers”, 1 },

UseDescriptorPinNumbers プロパティは、Windows が連番のピンの番号付けではなくネイティブのピンの番号付けを使うようにします。The UseDescriptorPinNumbers property tells Windows to use native pin numbering instead of sequential pin numbering. UseDescriptorPinNumbers プロパティが指定されていない場合、または値が 0 の場合は、Windows は既定の連番のピンの番号付けを使います。If the UseDescriptorPinNumbers property is not specified or its value is zero, Windows will default to Sequential pin numbering.

ネイティブのピンの番号付けを使う場合は、PinCount プロパティも指定する必要があります。If native pin numbering is used, you must also specify the PinCount property.

Package (2) { “GPIO-PinCount”, 54 },

PinCount プロパティは、GpioClx ドライバーの CLIENT_QueryControllerBasicInformation コールバックの TotalPins プロパティから返された値と一致する必要があります。The PinCount property should match the value returned through the TotalPins property in the CLIENT_QueryControllerBasicInformation callback of the GpioClx driver.

ボードの既存の公開されたドキュメントと最も互換性のある番号付けスキームを選択します。Choose the numbering scheme that is most compatible with existing published documentation for your board. たとえば、多くの既存のピン配列図が BCM2835 ピン番号を使っているため、Raspberry Pi はネイティブのピンの番号付けを使います。For example, Raspberry Pi uses native pin numbering because many existing pinout diagrams use the BCM2835 pin numbers. 200 個を超えるピンから 10 個のピンのみが公開されるため、既存のピン配列図が少なく、連番のピンの番号付けでは開発者のエクスペリエンスが単純化されるので、MinnowBoardMax は連番のピンの番号付けを使います。MinnowBoardMax uses sequential pin numbering because there are few existing pinout diagrams, and sequential pin numbering simplifies the developer experience because only 10 pins are exposed out of more than 200 pins. 連番のピンの番号付けを使うかネイティブのピンの番号付けを使うかの決定は、開発者の混乱を少なくすることを目的として行う必要があります。The decision to use sequential or native pin numbering should aim to reduce developer confusion.

GPIO ドライバーの要件GPIO Driver Requirements

  • 使用する必要があります。 GpioClxMust use GpioClx
  • SOC 上でメモリ マッピングする必要がありますMust be on-SOC memory mapped
  • エミュレートされた ActiveBoth 割り込み処理を使う必要がありますMust use emulated ActiveBoth interrupt handling

UARTUART

UART ドライバーが SerCx または SerCx2 を使用する場合、rhproxy を使用してこのドライバーをユーザー モードに公開することができます。If your UART driver uses SerCx or SerCx2, you can use rhproxy to expose the driver to usermode. GUID_DEVINTERFACE_COMPORT 型のデバイス インターフェイスを作成する UART ドライバーでは、rhproxy を使用する必要はありません。UART drivers that create a device interface of type GUID_DEVINTERFACE_COMPORT do not need to use rhproxy. インボックス Serial.sys ドライバーも、このようなドライバーの 1 つです。The inbox Serial.sys driver is one of these cases.

SerCx スタイルの UART をユーザー モードに公開するには、次のように UARTSerialBus リソースを宣言します。To expose a SerCx-style UART to usermode, declare a UARTSerialBus resource as follows.

// Index 2
UARTSerialBus(           // Pin 17, 19 of JP1, for SIO_UART2
    115200,                // InitialBaudRate: in bits ber second
    ,                      // BitsPerByte: default to 8 bits
    ,                      // StopBits: Defaults to one bit
    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
    ,                      // IsBigEndian: default to LittleEndian
    ,                      // Parity: Defaults to no parity
    ,                      // FlowControl: Defaults to no flow control
    32,                    // ReceiveBufferSize
    32,                    // TransmitBufferSize
    "\\_SB.URT2",          // ResourceSource: UART bus controller name
    ,
    ,
    ,
    )

ResourceSource フィールドのみが固定され、その他のすべてのフィールドは実行時にユーザーによって指定される値のプレースホルダーとなります。Only the ResourceSource field is fixed while all other fields are placeholders for values specified at runtime by the user.

付随するフレンドリ名の宣言は次のようになります。The accompanying friendly name declaration is:

Package(2) { "bus-UART-UART2", Package() { 2 }},

ユーザーがユーザー モードからバスにアクセスするために使う識別子である、フレンドリ名 “UART2” がコントローラーに割り当てられます。This assigns the friendly name “UART2” to the controller, which is the identifier users will use to access the bus from usermode.

実行時のピンの多重化Runtime Pin Muxing

ピンの多重化は、同じ物理ピンをさまざまな機能のために使う機能です。Pin muxing is the ability to use the same physical pin for different functions. I2C コントローラー、SPI コントローラー、GPIO コントローラーなどのいくつかのオンチップ周辺機器が、SOC の同じ物理ピンにルーティングされる可能性があります。Several different on-chip peripherals, such as an I2C controller, SPI controller, and GPIO controller, might be routed to the same physical pin on a SOC. 多重化ブロックは、任意の時間にどの機能がピンでアクティブになるかを制御します。The mux block controls which function is active on the pin at any given time. 従来は、ファームウェアが機能の割り当てを起動時に確立し、この割り当ては起動セッションを通じて静的なままでした。Traditionally, firmware is responsible for establishing function assignments at boot, and this assignment remains static through the boot session. 実行時のピンの多重化は、実行時にピンの機能の割り当てを再構成する機能を追加します。Runtime pin muxing adds the ability to reconfigure pin function assignments at runtime. 実行時にユーザーがピンの機能を選択できるようにすると、ユーザーがボードのピンをすばやく再構成できるようになることで開発が高速化され、静的な構成の場合よりもハードウェアが広い範囲のアプリケーションをサポートできるようになります。Enabling users to choose a pin’s function at runtime speeds development by enabling users to quickly reconfigure a board’s pins, and enables hardware to support a broader range of applications than would a static configuration.

追加のコードを記述しなくても、ユーザーは GPIO、I2C、SPI、UART の多重化のサポートを利用できます。Users consume muxing support for GPIO, I2C, SPI, and UART without writing any additional code. ユーザーが OpenPin() または FromIdAsync() を使って GPIO を開くと、基になる物理ピンが要求された機能に対して自動的に多重化されます。When a user opens a GPIO or bus using OpenPin() or FromIdAsync(), the underlying physical pins are automatically muxed to the requested function. ピンが既に別の機能により使われている場合は、OpenPin() または FromIdAsync() の呼び出しは失敗します。If the pins are already in use by a different function, the OpenPin() or FromIdAsync() call will fail. GpioPinI2cDeviceSpiDeviceSerialDevice オブジェクトを廃棄することでユーザーがデバイスを閉じると、ピンが解放され、後で別の機能のために開くことができるようになります。When the user closes the device by disposing the GpioPin, I2cDevice, SpiDevice, or SerialDevice object, the pins are released, allowing them to later be opened for a different function.

Windows では、GpioClxSpbCxSerCx フレームワークにピンの多重化の組み込みサポートが含まれています。Windows contains built-in support for pin muxing in the GpioClx, SpbCx, and SerCx frameworks. これらのフレームワークは、GPIO ピンまたはバスがアクセスされたときに正しい機能にピンを自動的に切り替えるために、連携して機能します。These frameworks work together to automatically switch a pin to the correct function when a GPIO pin or bus is accessed. 複数のクライアント間での競合を避けるために、ピンへのアクセスは適切に判別されます。Access to the pins is arbitrated to prevent conflicts among multiple clients. この組み込みサポートに加えて、ピンの多重化のためのインターフェイスとプロトコルは汎用のため、追加のデバイスとシナリオをサポートするために拡張できます。In addition to this built-in support, the interfaces and protocols for pin muxing are general purpose and can be extended to support additional devices and scenarios.

このドキュメントでは、まずピンの多重化に関与する基となるインターフェイスとプロトコルについて説明してから、GpioClx、SpbCx、SerCx コントローラー ドライバーに対してピンの多重化のサポートを追加する方法について説明します。This document first describes the underlying interfaces and protocols involved in pin muxing, and then describes how to add support for pin muxing to GpioClx, SpbCx, and SerCx controller drivers.

ピンの多重化のアーキテクチャPin Muxing Architecture

このセクションでは、ピンの多重化に関与する基となるインターフェイスとプロトコルについて説明します。This section describes the underlying interfaces and protocols involved in pin muxing. 基となるプロトコルの知識は、GpioClx/SpbCx/SerCx ドライバーによるピンの多重化のサポートに必ずしも必要ではありません。Knowledge of the underlying protocols is not necessarily needed to support pin muxing with GpioClx/SpbCx/SerCx drivers. GpioCls/SpbCx/SerCx ドライバーによるピンの多重化のサポート方法について詳しくは、「GpioClx クライアント ドライバーでのピンの多重化のサポートの実装」と「SpbCx および SerCx コントローラー ドライバーでの多重化のサポートの使用」をご覧ください。For details on how to support pin muxing with GpioCls/SpbCx/SerCx drivers, see Implementing pin muxing support in GpioClx client drivers and Consuming muxing support in SpbCx and SerCx controller drivers.

ピンの多重化は、複数のコンポーネントが連携することで行われます。Pin muxing is accomplished by the cooperation of several components.

  • ピンの多重化のサーバーは、ピンの多重化の制御ブロックを制御するドライバーです。Pin muxing servers – these are drivers that control the pin muxing control block. ピンの多重化のサーバーは、多重化のリソースを予約するための要求 (IRP_MJ_CREATE 要求を使用) と、ピンの機能を切り替えるための要求 (IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS 要求を使用) を介して、クライアントからピンの多重化の要求を受け取ります。Pin muxing servers receive pin muxing requests from clients via requests to reserve muxing resources (via IRP_MJ_CREATE) requests, and requests to switch a pin’s function (via IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS requests). 多重化ブロックが GPIO ブロックの一部である場合があるため、通常はピンの多重化のサーバーは GPIO ドライバーです。The pin muxing server is usually the GPIO driver, since the muxing block is sometimes part of the GPIO block. 多重化ブロックが別個の周辺機器の場合でも、GPIO ドライバーは多重化機能を配置するための理にかなった場所となります。Even if the muxing block is a separate peripheral, the GPIO driver is a logical place to put muxing functionality.
  • ピンの多重化のクライアントは、ピンの多重化を使うドライバーです。Pin muxing clients – these are drivers that consume pin muxing. ピンの多重化のクライアントは ACPI ファームウェアからピンの多重化のリソースを受け取ります。Pin muxing clients receive pin muxing resources from ACPI firmware. ピンの多重化のリソースは接続リソースの一種で、リソース ハブによって管理されます。Pin muxing resources are a type of connection resource and are managed by the resource hub. ピンの多重化のクライアントは、ハンドルをリソースに対して開くことでピンの多重化のリソースを予約します。Pin muxing clients reserve pin muxing resources by opening a handle to the resource. ハードウェアの変更を有効にするために、クライアントは IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS 要求を送信して構成をコミットする必要があります。To effect a hardware change, clients must commit the configuration by sending an IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS request. クライアントはハンドルを閉じることでピンの多重化のリソースを解放し、この時点で多重化構成は既定の状態に戻ります。Clients release pin muxing resources by closing the handle, at which point muxing configuration is reverted to its default state.
  • ACPI ファームウェアは、MsftFunctionConfig() リソースにより多重化構成を指定します。ACPI firmware – specifies muxing configuration with MsftFunctionConfig() resources. MsftFunctionConfig リソースは、どのピンがどの多重化構成でクライアントにより必要とされるかを表します。MsftFunctionConfig resources express which pins, in which muxing configuration, are required by a client. MsftFunctionConfig リソースには、機能番号、プル構成、ピン番号の一覧が含まれます。MsftFunctionConfig resources contain function number, pull configuration, and list of pin numbers. MsftFunctionConfig リソースはハードウェア リソースとしてピンの多重化のクライアントに提供され、GPIO および SPB 接続リソースと同様に、ドライバーによって PrepareHardware コールバックで受け取られます。MsftFunctionConfig resources are supplied to pin muxing clients as hardware resources, which are received by drivers in their PrepareHardware callback similarly to GPIO and SPB connection resources. クライアントは、リソースに対してハンドルを開くために使うことができるリソース ハブ ID を受け取ります。Clients receive a resource hub ID which can be used to open a handle to the resource.

MsftFunctionConfig() 記述子を含んでいる ASL ファイルをコンパイルするには、/MsftInternal コマンド ライン スイッチを asl.exe に渡す必要があります。これは、これらの記述子が、ACPI 作業部会で現在検討中であるためです。You must pass the /MsftInternal command line switch to asl.exe to compile ASL files containing MsftFunctionConfig() descriptors since these descriptors are currently under review by the ACPI working committee. たとえば次のようになります。asl.exe /MsftInternal dsdt.aslFor example: asl.exe /MsftInternal dsdt.asl

ピンの多重化に関連する操作の順序を次に示します。The sequence of operations involved in pin muxing is shown below.

ピンの多重化のクライアントとサーバーの相互作用

  1. クライアントは、EvtDevicePrepareHardware() コールバックで、ACPI ファームウェアから MsftFunctionConfig リソースを受け取ります。The client receives MsftFunctionConfig resources from ACPI firmware in its EvtDevicePrepareHardware() callback.
  2. クライアントはリソース ハブ ヘルパー関数 RESOURCE_HUB_CREATE_PATH_FROM_ID() を使ってリソース ID からパスを作成し、(ZwCreateFile()IoGetDeviceObjectPointer()、または WdfIoTargetOpen() を使って) そのパスに対してハンドルを開きます。The client uses the resource hub helper function RESOURCE_HUB_CREATE_PATH_FROM_ID() to create a path from the resource ID, then opens a handle to the path (using ZwCreateFile(), IoGetDeviceObjectPointer(), or WdfIoTargetOpen()).
  3. サーバーがリソース ハブ ヘルパー関数 RESOURCE_HUB_ID_FROM_FILE_NAME() を使ってファイル パスからリソース ハブ ID を抽出してから、リソース ハブを照会してリソース記述子を取得します。The server extracts the resource hub ID from the file path using resource hub helper functions RESOURCE_HUB_ID_FROM_FILE_NAME(), then queries the resource hub to get the resource descriptor.
  4. サーバーは記述子内の各ピンの共有の判別を実行し、IRP_MJ_CREATE 要求を完了します。The server performs sharing arbitration for each pin in the descriptor and completes the IRP_MJ_CREATE request.
  5. クライアントが受け取ったハンドルに対する IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS 要求を生成します。The client issues an IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS request on the received handle.
  6. IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS に応えて、指定された機能を各ピンでアクティブにすることで、サーバーがハードウェアの多重化操作を実行します。In response to IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS, the server performs the hardware muxing operation by making the specified function active on each pin.
  7. 要求されたピンの多重化構成に応じた操作でクライアントの処理が先に進みます。The client proceeds with operations that depend on the requested pin muxing configuration.
  8. クライアントでピンの多重化が不要になると、ハンドルが閉じられます。When the client no longer requires the pins to be muxed, it closes the handle.
  9. 閉じられたハンドルに応じて、サーバーがピンを初期状態に戻します。In response to the handle being closed, the server reverts the pins back to their initial state.

ピンの多重化のクライアントのためのプロトコルの説明Protocol description for pin muxing clients

このセクションでは、クライアントがピンの多重化機能を使う方法について説明します。This section describes how a client consumes pin muxing functionality. コントローラー ドライバーの代わりにフレームワークがこのプロトコルを実装するため、SerCx および SpbCx コントローラー ドライバーには適用されません。This does not apply to SerCx and SpbCx controller drivers, since the frameworks implement this protocol on behalf of controller drivers.

リソースの解析Parsing resources

WDF ドライバーが EvtDevicePrepareHardware() ルーチンで MsftFunctionConfig() リソースを受け取ります。A WDF driver receives MsftFunctionConfig() resources in its EvtDevicePrepareHardware() routine. MsftFunctionConfig リソースは、次のフィールドで識別できます。MsftFunctionConfig resources can be identified by the following fields:

CM_PARTIAL_RESOURCE_DESCRIPTOR::Type = CmResourceTypeConnection
CM_PARTIAL_RESOURCE_DESCRIPTOR::u.Connection.Class = CM_RESOURCE_CONNECTION_CLASS_FUNCTION_CONFIG
CM_PARTIAL_RESOURCE_DESCRIPTOR::u.Connection.Type = CM_RESOURCE_CONNECTION_TYPE_FUNCTION_CONFIG

EvtDevicePrepareHardware() ルーチンは、次のように MsftFunctionConfig リソースを展開します。An EvtDevicePrepareHardware() routine might extract MsftFunctionConfig resources as follows:

EVT_WDF_DEVICE_PREPARE_HARDWARE evtDevicePrepareHardware;

_Use_decl_annotations_
NTSTATUS
evtDevicePrepareHardware (
    WDFDEVICE WdfDevice,
    WDFCMRESLIST ResourcesTranslated
    )
{
    PAGED_CODE();

    LARGE_INTEGER connectionId;
    ULONG functionConfigCount = 0;

    const ULONG resourceCount = WdfCmResourceListGetCount(ResourcesTranslated);
    for (ULONG index = 0; index < resourceCount; ++index) {
        const CM_PARTIAL_RESOURCE_DESCRIPTOR* resDescPtr =
            WdfCmResourceListGetDescriptor(ResourcesTranslated, index);

        switch (resDescPtr->Type) {
        case CmResourceTypeConnection:
            switch (resDescPtr->u.Connection.Class) {
            case CM_RESOURCE_CONNECTION_CLASS_FUNCTION_CONFIG:
                switch (resDescPtr->u.Connection.Type) {
                case CM_RESOURCE_CONNECTION_TYPE_FUNCTION_CONFIG:
                    switch (functionConfigCount) {
                    case 0:
                        // save the connection ID
                        connectionId.LowPart = resDescPtr->u.Connection.IdLowPart;
                        connectionId.HighPart = resDescPtr->u.Connection.IdHighPart;
                        break;
                    } // switch (functionConfigCount)
                    ++functionConfigCount;
                    break; // CM_RESOURCE_CONNECTION_TYPE_FUNCTION_CONFIG

                } // switch (resDescPtr->u.Connection.Type)
                break; // CM_RESOURCE_CONNECTION_CLASS_FUNCTION_CONFIG
            } // switch (resDescPtr->u.Connection.Class)
            break;
        } // switch
    } // for (resource list)

    if (functionConfigCount < 1) {
        return STATUS_INVALID_DEVICE_CONFIGURATION;
    }
    // TODO: save connectionId in the device context for later use

    return STATUS_SUCCESS;
}

リソースの予約とコミットReserving and committing resources

クライアントでピンの多重化が必要な場合、MsftFunctionConfig リソースを予約してコミットします。When a client wants to mux pins, it reserves and commits the MsftFunctionConfig resource. 次の例は、クライアントが MsftFunctionConfig リソースを予約してコミットする方法を示しています。The following example shows how a client might reserve and commit MsftFunctionConfig resources.

_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS AcquireFunctionConfigResource (
    WDFDEVICE WdfDevice,
    LARGE_INTEGER ConnectionId,
    _Out_ WDFIOTARGET* ResourceHandlePtr
    )
{
    PAGED_CODE();

    //
    // Form the resource path from the connection ID
    //
    DECLARE_UNICODE_STRING_SIZE(resourcePath, RESOURCE_HUB_PATH_CHARS);
    NTSTATUS status = RESOURCE_HUB_CREATE_PATH_FROM_ID(
            &resourcePath,
            ConnectionId.LowPart,
            ConnectionId.HighPart);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Create a WDFIOTARGET
    //
    WDFIOTARGET resourceHandle;
    status = WdfIoTargetCreate(WdfDevice, WDF_NO_ATTRIBUTES, &resourceHandle);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Reserve the resource by opening a WDFIOTARGET to the resource
    //
    WDF_IO_TARGET_OPEN_PARAMS openParams;
    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(
        &openParams,
        &resourcePath,
        FILE_GENERIC_READ | FILE_GENERIC_WRITE);

    status = WdfIoTargetOpen(resourceHandle, &openParams);
    if (!NT_SUCCESS(status)) {
        return status;
    }
    //
    // Commit the resource
    //
    status = WdfIoTargetSendIoctlSynchronously(
            resourceHandle,
            WDF_NO_HANDLE,      // WdfRequest
            IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS,
            nullptr,            // InputBuffer
            nullptr,            // OutputBuffer
            nullptr,            // RequestOptions
            nullptr);           // BytesReturned

    if (!NT_SUCCESS(status)) {
        WdfIoTargetClose(resourceHandle);
        return status;
    }

    //
    // Pins were successfully muxed, return the handle to the caller
    //
    *ResourceHandlePtr = resourceHandle;
    return STATUS_SUCCESS;
}

ドライバーは、後で閉じることができるように、WDFIOTARGET をいずれかのコンテキスト領域に格納する必要があります。The driver should store the WDFIOTARGET in one of its context areas so that it can be closed later. ドライバーが多重化構成を解放する準備ができたら、WdfObjectDelete() を呼び出すか、WDFIOTARGET を再利用する場合には WdfIoTargetClose() を呼び出してリソース ハンドルを閉じる必要があります。When the driver is ready to release the muxing configuration, it should close the resource handle by calling WdfObjectDelete(), or WdfIoTargetClose() if you intend to reuse the WDFIOTARGET.

    WdfObjectDelete(resourceHandle);

クライアントがそのリソース ハンドルを閉じると、ピンは多重化されて初期状態に戻され、別のクライアントで取得できるようになります。When the client closes its resource handle, the pins are muxed back to their initial state, and can now be acquired by a different client.

ピンの多重化のサーバーのためのプロトコルの説明Protocol description for pin muxing servers

このセクションでは、ピンの多重化のサーバーがその機能をクライアントに公開する方法について説明します。This section describes how a pin muxing server exposes its functionality to clients. クライアント ドライバーの代わりにフレームワークがこのプロトコルを実装するため、GpioClx ミニポート ドライバーには適用されません。This does not apply to GpioClx miniport drivers, since the framework implements this protocol on behalf of client drivers. GpioClx クライアント ドライバーでピンの多重化をサポートする方法について詳しくは、「GpioClx クライアント ドライバーでの多重化のサポートの実装」をご覧ください。For details on how to support pin muxing in GpioClx client drivers, see Implementing muxing support in GpioClx Client Drivers.

IRP_MJ_CREATE 要求の処理Handling IRP_MJ_CREATE requests

クライアントは、ピンの多重化のリソースを予約するときにリソースに対してハンドルを開きます。Clients open a handle to a resource when they want to reserve a pin muxing resource. ピンの多重化のサーバーが、リソース ハブからの再解析操作により IRP_MJ_CREATE 要求を受け取ります。A pin muxing server receives IRP_MJ_CREATE requests by way of a reparse operation from the resource hub. IRP_MJ_CREATE 要求の末尾のパス コンポーネントには、16 進数形式の 64 ビット整数であるリソース ハブ ID が含まれています。The trailing path component of the IRP_MJ_CREATE request contains the resource hub ID, which is a 64-bit integer in hexadecimal format. サーバーは、reshub.h から RESOURCE_HUB_ID_FROM_FILE_NAME() を使ってファイル名からリソース ハブ ID を抽出し、IOCTL_RH_QUERY_CONNECTION_PROPERTIES をリソース ハブに送信して MsftFunctionConfig() 記述子を取得する必要があります。The server should extract the resource hub ID from the filename using RESOURCE_HUB_ID_FROM_FILE_NAME() from reshub.h, and send IOCTL_RH_QUERY_CONNECTION_PROPERTIES to the resource hub to obtain the MsftFunctionConfig() descriptor.

サーバーは記述子を検証して、共有モードとピンの一覧を記述子から抽出する必要があります。The server should validate the descriptor and extract the sharing mode and pin list from the descriptor. その後、ピンの共有の判別を実行し、成功した場合には、要求を完了する前にピンを予約済みとしてマークします。It should then perform sharing arbitration for the pins, and if successful, mark the pins as reserved before completing the request.

ピンの一覧の各ピンで共有の判別が成功すると、全体的な共有の判別が成功します。Sharing arbitration succeeds overall if sharing arbitration succeeds for each pin in the pin list. 各ピンは次のように判別する必要があります。Each pin should be arbitrated as follows:

  • ピンがまだ予約されていない場合、共有の判別は成功します。If the pin is not already reserved, sharing arbitration succeeds.
  • ピンが既に排他的に予約されている場合、共有の判別は失敗します。If the pin is already reserved as exclusive, sharing arbitration fails.
  • ピンが既に共有として予約されていて、If the pin is already reserved as shared,
    • 着信要求が共有されている場合、共有の判定は成功します。and the incoming request is shared, sharing arbitration succeeds.
    • 着信要求が排他的な場合、共有の判別は失敗します。and the incoming request is exclusive, sharing arbitration fails.

共有の判別に失敗した場合は、STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE で要求を完了する必要があります。If sharing arbitration fails, the request should be completed with STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE. 共有の判別に成功した場合は、STATUS_SUCCESS で要求を完了する必要があります。If sharing arbitration succeeds, the request should completed with STATUS_SUCCESS.

着信要求の共有モードは、IrpSp->Parameters.Create.ShareAccess ではなく MsftFunctionConfig 記述子から取得する必要があることに注意してください。Note that the sharing mode of the incoming request should be taken from the MsftFunctionConfig descriptor, not IrpSp->Parameters.Create.ShareAccess.

IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS 要求の処理Handling IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS requests

クライアントがハンドルを開くことで MsftFunctionConfig リソースの予約に成功した後は、IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS を送信して実際のハードウェア多重化操作を実行するようサーバーに要求することができます。After the client has successfully reserved a MsftFunctionConfig resource by opening a handle, it can send IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS to request the server to perform the actual hardware muxing operation. サーバーが IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS を受け取ると、ピンの一覧の各ピンは、When the server receives IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS, for each pin in the pin list it should

  • PNP_FUNCTION_CONFIG_DESCRIPTOR 構造の PinConfiguration メンバーで指定されたプル モードをハードウェアに設定する必要があります。Set the pull mode specified in the PinConfiguration member of the PNP_FUNCTION_CONFIG_DESCRIPTOR structure into hardware.
  • PNP_FUNCTION_CONFIG_DESCRIPTOR 構造の FunctionNumber メンバーによって指定された機能に対してピンを多重化する必要があります。Mux the pin to the function specified by the FunctionNumber member of the PNP_FUNCTION_CONFIG_DESCRIPTOR structure.

サーバーはその後、STATUS_SUCCESS を使って要求を完了する必要があります。The server should then complete the request with STATUS_SUCCESS.

FunctionNumber の意味はサーバーによって定義され、サーバーが MsftFunctionConfig のフィールドをどのように解釈して、MsftFunctionConfig 記述子が作成されたかがわかります。The meaning of FunctionNumber is defined by the server, and it is understood that the MsftFunctionConfig descriptor was authored with knowledge of how the server interprets this field.

ハンドルが閉じられたときにサーバーは IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS が受け取られたときの構成にピンを戻す必要があるため、ピンの状態を変更する前に保存する必要があることに注意してください。Remember that when the handle is closed, the server will have to revert the pins to the configuration they were in when IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS was received, so the server may need to save the pins’ state before modifying them.

IRP_MJ_CLOSE 要求の処理Handling IRP_MJ_CLOSE requests

クライアントで多重化のリソースが不要になったときは、そのハンドルを閉じます。When a client no longer requires a muxing resource, it closes its handle. サーバーが IRP_MJ_CLOSE 要求を受け取ったときに、IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS が受け取られたときの状態にピンを戻す必要があります。When a server receives a IRP_MJ_CLOSE request, it should revert the pins to the state they were in when IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS was received. クライアントが IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS を送信しない場合、操作は不要です。If the client never sent a IOCTL_GPIO_COMMIT_FUNCTION_CONFIG_PINS, no action is necessary. サーバーはその後、共有の判別に関して利用可能とピンをマークし、STATUS_SUCCESS を使って要求を完了する必要があります。The server should then mark the pins as available with respect to sharing arbitration, and complete the request with STATUS_SUCCESS. IRP_MJ_CLOSE の処理と IRP_MJ_CREATE の処理を正しく同期してください。Be sure to properly synchronize IRP_MJ_CLOSE handling with IRP_MJ_CREATE handling.

ACPI テーブルの作成のガイドラインAuthoring guidelines for ACPI tables

このセクションでは、クライアント ドライバーに多重化のリソースを指定する方法について説明します。This section describes how to supply muxing resources to client drivers. MsftFunctionConfig() リソースを含むテーブルをコンパイルするために、Microsoft ASL コンパイラ ビルド 14327 以降が必要となることに注意してください。Note that you will need Microsoft ASL compiler build 14327 or later to compile tables containing MsftFunctionConfig() resources. MsftFunctionConfig() リソースは、pin マルチプレキシング クライアントにハードウェア リソースとして指定されます。MsftFunctionConfig() resources are supplied to pin muxing clients as hardware resources. MsftFunctionConfig() リソースは SPB は、通常 pin マルチプレキシングの変更が必要なドライバーとシリアル コント ローラーのドライバーを指定する必要がありますが、コント ローラー ドライバー ハンドル マルチプレキシング configuration 以降を SPB シリアルの周辺機器のドライバーを指定しないで必要があります。MsftFunctionConfig() resources should be supplied to drivers that require pin muxing changes, which are typically SPB and serial controller drivers, but should not be supplied to SPB and serial peripheral drivers, since the controller driver handles muxing configuration. MsftFunctionConfig() ACPI マクロは、次のように定義されています。The MsftFunctionConfig() ACPI macro is defined as follows:

  MsftFunctionConfig(Shared/Exclusive
                PinPullConfig,
                FunctionNumber,
                ResourceSource,
                ResourceSourceIndex,
                ResourceConsumer/ResourceProducer,
                VendorData) { Pin List }

  • Shared/Exclusive – 排他的な場合、このピンは一度に単一のクライアントで取得できます。Shared/Exclusive – If exclusive, this pin can be acquired by a single client at a time. 共有の場合、複数の共有クライアントがリソースを取得できます。If shared, multiple shared clients can acquire the resource. 調整がされていない複数のクライアントによる変更可能なリソースへのアクセスを許可すると、データの競合につながり、予期しない結果となる可能性があるため、常に排他的に設定します。Always set this to exclusive since allowing multiple uncoordinated clients to access a mutable resource can lead to data races and therefore unpredictable results.
  • PinPullConfig – 次のいずれかに設定します。PinPullConfig – one of
    • PullDefault – SOC 定義の電源投入時の既定のプル構成を使いますPullDefault – use the SOC-defined power-on default pull configuration
    • PullUp – プル アップ抵抗を有効にしますPullUp – enable pull-up resistor
    • PullDown – プル ダウン抵抗を有効にしますPullDown – enable pull-down resistor
    • PullNone – すべてのプル抵抗を無効にしますPullNone – disable all pull resistors
  • FunctionNumber – 多重化にプログラムする機能番号です。FunctionNumber – the function number to program into the mux.
  • ResourceSource – ピンの多重化のサーバーの ACPI 名前空間パスですResourceSource – The ACPI namespace path of the pin muxing server
  • ResourceSourceIndex – 0 に設定しますResourceSourceIndex – set this to 0
  • ResourceConsumer/ResourceProducer – ResourceConsumer に設定しますResourceConsumer/ResourceProducer – set this to ResourceConsumer
  • VendorData – ピンの多重化のサーバーによって意味が定義される、オプションのバイナリ データです。VendorData – optional binary data whose meaning is defined by the pin muxing server. 通常は空白のままにしますThis should usually be left blank
  • Pin List – 構成を適用するピン番号のコンマ区切りの一覧です。Pin List – a comma separated list of pin numbers to which the configuration applies. ピンの多重化のサーバーが GpioClx ドライバーの場合、これらは GPIO ピン番号になり、GpioIo 記述子のピン番号と同じ意味を持ちます。When the pin muxing server is a GpioClx driver, these are GPIO pin numbers and have the same meaning as pin numbers in a GpioIo descriptor.

次の例では、MsftFunctionConfig() リソースを I2C コントローラー ドライバーに提供する方法を示します。The following example shows how one might supply a MsftFunctionConfig() resource to an I2C controller driver.

Device(I2C1)
{
    Name(_HID, "BCM2841")
    Name(_CID, "BCMI2C")
    Name(_UID, 0x1)
    Method(_STA)
    {
        Return(0xf)
    }
    Method(_CRS, 0x0, NotSerialized)
    {
        Name(RBUF, ResourceTemplate()
        {
            Memory32Fixed(ReadWrite, 0x3F804000, 0x20)
            Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { 0x55 }
            MsftFunctionConfig(Exclusive, PullUp, 4, "\\_SB.GPI0", 0, ResourceConsumer, ) { 2, 3 }
        })
        Return(RBUF)
    }
}

通常コントローラー ドライバーに必要なメモリと割り込みリソースに加えて、MsftFunctionConfig() リソースも指定します。In addition to the memory and interrupt resources typically required by a controller driver, a MsftFunctionConfig() resource is also specified. このリソースにより、2 と 3 - で、[デバイス] ノードで管理のピンを配置する I2C コント ローラー ドライバー \_SB します。GPIO0 – 関数 4 プルアップ抵抗が有効になっているとします。This resource enables the I2C controller driver to put pins 2 and 3 - managed by the device node at \_SB.GPIO0 – in function 4 with pull-up resistor enabled.

GpioClx クライアント ドライバーでの多重化サポートのサポートSupporting muxing support in GpioClx client drivers

GpioClx pin マルチプレキシングの組み込みサポートしています。GpioClx has built-in support for pin muxing. GpioClx ミニポート ドライバー (“GpioClx クライアント ドライバー” とも呼ばれます) が GPIO コントローラー ハードウェアを制御します。GpioClx miniport drivers (also referred to as “GpioClx client drivers”), drive GPIO controller hardware. Windows 10 ビルド 14327 以降では、GpioClx ミニポート ドライバーは 2 つの新しい DDI を実装することでピンの多重化のサポートを追加することができます。As of Windows 10 build 14327, GpioClx miniport drivers can add support for pin muxing by implementing two new DDIs:

  • CLIENT_ConnectFunctionConfigPins – GpioClx によって呼び出され、ミニポート ドライバーが指定された多重化構成を適用するように指示を出します。CLIENT_ConnectFunctionConfigPins – called by GpioClx to command the miniport driver to apply the specified muxing configuration.
  • CLIENT_DisconnectFunctionConfigPins – GpioClx によって呼び出され、ミニポート ドライバーが多重化構成を戻すように指示を出します。CLIENT_DisconnectFunctionConfigPins – called by GpioClx to command the miniport driver to revert the muxing configuration.

これらのルーチンの説明については、「GpioClx イベント コールバック関数」をご覧ください。See GpioClx Event Callback Functions for a description of these routines.

これらの 2 つの新しい DDI に加えて、既存の DDI もピンの多重化の互換性の監査対象とする必要があります。In addition to these two new DDIs, existing DDIs should be audited for pin muxing compatibility:

  • CLIENT_ConnectIoPins/CLIENT_ConnectInterrupt – CLIENT_ConnectIoPins は GpioClx によって呼び出され、ミニポート ドライバーが GPIO 入力または出力のための一連のピンを構成するように指示を出します。CLIENT_ConnectIoPins/CLIENT_ConnectInterrupt – CLIENT_ConnectIoPins is called by GpioClx to command the miniport driver to configure a set pins for GPIO input or output. GPIO は MsftFunctionConfig と相互に排他的なため、GPIO と MsftFunctionConfig に同時にピンが接続されることはありません。GPIO is mutually exclusive with MsftFunctionConfig, meaning a pin will never be connected for GPIO and MsftFunctionConfig at the same time. ピンの既定の機能が GPIO である必要はないため、ConnectIoPins が呼び出されたときにピンが必ずしも GPIO に多重化されないとは限りません。Since a pin’s default function is not required to be GPIO, a pin may not necessarily not be muxed to GPIO when ConnectIoPins is called. ConnectIoPins は、多重化操作を含む、GPIO IO のためのピンの準備に必要なすべての操作を実行するために必要です。ConnectIoPins is required to perform all operations necessary to make the pin ready for GPIO IO, including muxing operations. 割り込みは GPIO 入力の特殊なケースと考えることができるため、CLIENT_ConnectInterrupt も同様に動作する必要があります。CLIENT_ConnectInterrupt should behave similarly, since interrupts can be thought of as a special case of GPIO input.
  • CLIENT_DisconnectIoPins/CLIENT_DisconnectInterrupt – これらのルーチンは、PreserveConfiguration フラグが指定されていない限り、CLIENT_ConnectIoPins/CLIENT_ConnectInterrupt が呼び出されたときの状態にピンを戻す必要があります。CLIENT_DisconnectIoPins/CLIENT_DisconnectInterrupt – These routine should return pins to the state they were in when CLIENT_ConnectIoPins/CLIENT_ConnectInterrupt was called, unless the PreserveConfiguration flag is specified. ピンの方向を既定の状態に戻すだけでなく、ミニポートが各ピンの多重化の状態を _Connect routine が呼び出されたときの状態に戻す必要もあります。In addition to reverting the direction of pins to their default state, the miniport should also revert each pin’s muxing state to the state it was in when the _Connect routine was called.

たとえば、ピンの既定の多重化構成が UART で、ピンが GPIO としても使うことができると想定します。For example, assume that a pin’s default muxing configuration is UART, and the pin can also be used as GPIO. GPIO のピンの接続のために CLIENT_ConnectIoPins が呼び出されると、ピンを GPIO に多重化する必要があり、CLIENT_DisconnectIoPins でピンを UART に多重化して戻す必要があります。When CLIENT_ConnectIoPins is called to connect the pin for GPIO, it should mux the pin to GPIO, and in CLIENT_DisconnectIoPins, it should mux the pin back to UART. 一般的に、_Disconnect ルーチンは _Connect ルーチンによって行われた操作を元に戻す必要があります。In general, the _Disconnect routines should undo operations done by the _Connect routines.

SpbCx および SerCx コントローラー ドライバーでの多重化のサポートSupporting muxing in SpbCx and SerCx controller drivers

Windows 10 ビルド 14327 以降では、SpbCx および SerCx コントローラー ドライバーをコントローラー ドライバー自体のコードを変更せずにピンの多重化のクライアントにできるようにする、ピンの多重化のための組み込みサポートが SpbCx および SerCx フレームワークに含まれています。As of Windows 10 build 14327, the SpbCx and SerCx frameworks contain built-in support for pin muxing that enables SpbCx and SerCx controller drivers to be pin muxing clients without any code changes to the controller drivers themselves. 拡張機能によって、多重化対応の SpbCx/SerCx コントローラー ドライバーに接続する SpbCx/SerCx 周辺機器ドライバーがピンの多重化アクティビティをトリガーします。By extension, any SpbCx/SerCx peripheral driver that connects to a muxing-enabled SpbCx/SerCx controller driver will trigger pin muxing activity.

次の図は、これらの各コンポーネント間の依存関係を示しています。The following diagram shows the dependencies between each of these components. 図に示されているように、ピンの多重化は SerCx および SpbCx コントローラー ドライバーからの依存関係を GPIO ドライバーに導入し、通常はこれにより多重化が行われます。As you can see, pin muxing introduces a dependency from SerCx and SpbCx controller drivers to the GPIO driver, which is usually responsible for muxing.

ピンの多重化の依存関係

デバイスの初期化時に、SpbCx および SerCx フレームワークがハードウェア リソースとしてデバイスに提供されたすべての MsftFunctionConfig() リソースを解析します。At device initialization time, the SpbCx and SerCx frameworks parse all MsftFunctionConfig() resources supplied as hardware resources to the device. SpbCx/SerCx はその後、必要に応じてピンの多重化のリソースを取得および解放します。SpbCx/SerCx then acquire and release the pin muxing resources on demand.

SpbCx ピン留めマルチプレキシング構成が適用されます、 irp_mj_create 用ハンドラーを呼び出すクライアント ドライバーの直前にEvtSpbTargetConnect()コールバック。SpbCx applies pin muxing configuration in its IRP_MJ_CREATE handler, just before calling the client driver’s EvtSpbTargetConnect() callback. 多重化構成を適用できなかった場合、コントローラー ドライバーの EvtSpbTargetConnect() コールバックは呼び出されません。If muxing configuration could not be applied, the controller driver’s EvtSpbTargetConnect() callback will not be called. そのため、SPB コントローラー ドライバーは EvtSpbTargetConnect() が呼び出されたときまでにピンが SPB 機能に対して多重化されていると想定することができます。Therefore, an SPB controller driver may assume that pins are muxed to the SPB function by the time EvtSpbTargetConnect() is called.

SpbCx pin でのマルチプレキシングの構成を元に戻します。 その未完了コント ローラーのドライバーを起動した直後、ハンドラー EvtSpbTargetDisconnect()コールバック。SpbCx reverts pin muxing configuration in its IRP_MJ_CLOSE handler, just after invoking the controller driver’s EvtSpbTargetDisconnect() callback. その結果、周辺機器ドライバーが SPB コントローラー ドライバーに対してハンドルを開くたびにピンが SPB 機能に対して多重化され、周辺機器ドライバーがハンドルを閉じると多重化が終了します。The result is that pins are muxed to the SPB function whenever a peripheral driver opens a handle to the SPB controller driver, and are muxed away when the peripheral driver closes their handle.

SerCx 同様に動作します。SerCx behaves similarly. SerCx すべてを取得MsftFunctionConfig()内のリソースのirp_mj_create 用コント ローラーのドライバーを起動する前にハンドラー EvtSerCx2FileOpen()コールバックし、その未完了のすべてのリソースを解放コント ローラーのドライバーを起動した直後、ハンドラー EvtSerCx2FileCloseコールバック。SerCx acquires all MsftFunctionConfig() resources in its IRP_MJ_CREATE handler just before invoking the controller driver’s EvtSerCx2FileOpen() callback, and releases all resources in its IRP_MJ_CLOSE handler, just after invoking the controller driver’s EvtSerCx2FileClose callback.

SerCx および SpbCx コントローラー ドライバーのための動的なピンの多重化の実装では、特定の時間で SPB/UART 機能のピンの多重化が終了することを許容できる必要があります。The implication of dynamic pin muxing for SerCx and SpbCx controller drivers is that they must be able to tolerate pins being muxed away from SPB/UART function at certain times. コントローラー ドライバーは、EvtSpbTargetConnect() または EvtSerCx2FileOpen() が呼び出されるまでピンが多重化されないことを前提とする必要があります。Controller drivers need to assume that pins will not be muxed until EvtSpbTargetConnect() or EvtSerCx2FileOpen() is called. 次のコールバック中に必ずしもピンが SPB/UART 機能に多重化される必要はありません。Pins are not necessary muxed to SPB/UART function during the following callbacks. 次に示すのは完全な一覧ではありませんが、コントローラー ドライバーによって実装される最も一般的な PNP ルーチンを示しています。The following is not a complete list, but represents the most common PNP routines implemented by controller drivers.

  • DriverEntryDriverEntry
  • EvtDriverDeviceAddEvtDriverDeviceAdd
  • EvtDevicePrepareHardware/EvtDeviceReleaseHardwareEvtDevicePrepareHardware/EvtDeviceReleaseHardware
  • EvtDeviceD0Entry/EvtDeviceD0ExitEvtDeviceD0Entry/EvtDeviceD0Exit

検証Verification

rhproxy をテストする準備ができたら、次の手順を使用すると便利です。When you're ready to test rhproxy, it's helpful to use the following step-by-step procedure.

  1. SpbCxGpioClxSerCx の各コントローラー ドライバーの読み込みと正しい動作を確認します。Verify that each SpbCx, GpioClx, and SerCx controller driver is loading and operating correctly
  2. rhproxy がシステムに存在することを確認します。Verify that rhproxy is present on the system. Windows のエディションやビルドによっては、これが含まれていない場合があります。Some editions and builds of Windows do not have it.
  3. コンパイルし、rhproxy ノードを使用してロード ACPITABL.datCompile and load your rhproxy node using ACPITABL.dat
  4. rhproxy デバイス ノードが存在することを確認します。Verify that the rhproxy device node exists
  5. rhproxy が読み込まれ、開始されていることを確認します。Verify that rhproxy is loading and starting
  6. 想定されているデバイスがユーザー モードに公開されていることを確認します。Verify that the expected devices are exposed to usermode
  7. コマンド ラインから各デバイスを操作できることを確認します。Verify that you can interact with each device from the command line
  8. UWP アプリから各デバイスを操作できることを確認します。Verify that you can interact with each device from a UWP app
  9. HLK テストを実行します。Run HLK tests

コントローラー ドライバーを確認するVerify controller drivers

rhproxy は、システム上の他のデバイスもユーザー モードに公開するため、それらのデバイスが既に動作している場合にのみ動作します。Since rhproxy exposes other devices on the system to usermode, it only works if those devices are already working. 最初の手順では、それらのデバイス (公開する I2C、SPI、GPIO コントローラー) が既に動作していることを確認します。The first step is to verify that those devices - the I2C, SPI, GPIO controllers you wish to expose - are already working.

コマンド プロンプトで、次のコマンドを実行します。At the command prompt, run

devcon status *

出力を確認し、対象となるすべてのデバイスが起動されていることを確認します。Look at the output and verify that all devices of interest are started. デバイスに問題コードがある場合は、そのデバイスが読み込まれなかった理由を解決する必要があります。If a device has a problem code, you need to troubleshoot why that device is not loading. プラットフォームの最初の起動時にすべてのデバイスが有効になっている必要があります。All devices should have been enabled during initial platform bringup. SpbCxGpioClx、または SerCx コントローラー ドライバーのトラブルシューティングについては、このドキュメントでは説明しません。Troubleshooting SpbCx, GpioClx, or SerCx controller drivers is beyond the scope of this document.

rhproxy がシステムに存在することを確認するVerify that rhproxy is present on the system

rhproxy サービスがシステムに存在することを確認します。Verify that the rhproxy service is present on the system.

reg query HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\rhproxy

このレジストリ キーが存在しない場合、rhproxy はシステムに存在しません。If the reg key is not present, rhproxy doesn't exist on your system. rhproxy は、IoT Core のすべてのビルドと Windows Enterprise ビルド 15063 以降に存在します。Rhproxy is present on all builds of IoT Core and Windows Enterprise build 15063 and later.

ACPITABL.dat による ASL のコンパイルと読み込みCompile and load ASL with ACPITABL.dat

rhproxy ASL ノードを作成したら、これをコンパイルして読み込みます。Now that you've authored an rhproxy ASL node, it's time to compile and load it. システムの ACPI テーブルに追加できるスタンドアロン AML ファイルに、rhproxy ノードをコンパイルすることができます。You can compile the rhproxy node into a standalone AML file that can be appended to the system ACPI tables. または、システムの ACPI ソースにアクセスできる場合は、プラットフォームの ACPI テーブルに直接 rhproxy ノードを挿入できます。Alternatively, if you have access to your system's ACPI sources, you can insert the rhproxy node directly to your platform's ACPI tables. ただし、最初の起動時には、ACPITABL.dat を使用する方が容易な場合があります。However, during initial bringup it may be easier to use ACPITABL.dat.

  1. yourboard.asl という名前のファイルを作成し、DefinitionBlock 内に RHPX デバイス ノードを配置します。Create a file named yourboard.asl and put the RHPX device node inside a DefinitionBlock:
DefinitionBlock ("ACPITABL.dat", "SSDT", 1, "MSFT", "RHPROXY", 1)
{
    Scope (\_SB)
    {
        Device(RHPX)
        {
        ...
        }
    }
}
  1. ダウンロード、 WDKを見つけてasl.exeC:\Program Files (x86)\Windows Kits\10\Tools\x64\ACPIVerifyDownload the WDK and find asl.exe at C:\Program Files (x86)\Windows Kits\10\Tools\x64\ACPIVerify
  2. 次のコマンドを実行して ACPITABL.dat を生成します。Run the following command to generate ACPITABL.dat:
asl.exe yourboard.asl
  1. 生成された ACPITABL.dat ファイルを、テスト対象のシステムの c:\windows\system32 にコピーします。Copy the resulting ACPITABL.dat file to c:\windows\system32 on your system under test.
  2. テスト対象のシステムでテスト署名を有効にします。Turn on testsigning on your system under test:
bcdedit /set testsigning on
  1. テスト対象のシステムを再起動します。Reboot the system under test. システムが ACPITABL.dat で定義された ACPI テーブルをシステム ファームウェア テーブルに追加します。The system will append the ACPI tables defined in ACPITABL.dat to the system firmware tables.

rhproxy デバイス ノードが存在することを確認するVerify that the rhproxy device node exists

次のコマンドを実行して、rhproxy デバイス ノードを列挙します。Run the following command to enumerate the rhproxy device node.

devcon status *msft8000

devcon の出力は、デバイスが存在することを示している必要があります。The output of devcon should indicate that the device is present. デバイス ノードが存在しない場合、ACPI テーブルはシステムに正常に追加されていません。If the device node is not present, the ACPI tables were not successfully added to the system.

rhproxy が読み込まれ、開始されていることを確認するVerify that rhproxy is loading and starting

rhproxy の状態を確認します。Check the status of rhproxy:

devcon status *msft8000

出力が rhproxy が開始されていることを示している場合、rhproxy は正常に読み込まれて開始されています。If the output indicates that rhproxy is started, rhproxy has loaded and started successfully. 問題のコードが表示された場合は、調査する必要があります。If you see a problem code, you need to investigate. 一般的な問題コードには次のようなものがあります。Some common problem codes are:

  • 問題 51 - CM_PROB_WAITING_ON_DEPENDENCY -その依存関係のいずれかが読み込みに失敗したため、システムは rhproxy を開始していません。Problem 51 - CM_PROB_WAITING_ON_DEPENDENCY - The system is not starting rhproxy because one of it's dependencies has failed to load. これは、rhproxy に渡されたリソースが無効な ACPI ノードを指しているか、ターゲット デバイスが起動していないことを意味します。This means that either the resources passed to rhproxy point to invalid ACPI nodes, or the target devices are not starting. 最初に、すべてのデバイスが正常に実行されていることを再確認します (上記の「コントローラー ドライバーを確認する」を参照)。First, double check that all devices are running successfully (see 'Verify controller drivers' above). 次に、ASL を再確認し、すべてのリソース パス (例: \_SB.I2C1) が正しく、DSDT 内の有効なノードを指していることを確認します。Then, double check your ASL and ensure that all your resource paths (e.g. \_SB.I2C1) are correct and point to valid nodes in your DSDT.
  • 問題 10 - CM_PROB_FAILED_START - rhproxy を開始できませんでした。ほとんどの場合、リソースの解析の問題が原因です。Problem 10 - CM_PROB_FAILED_START - Rhproxy failed to start, most likely because of a resource parsing issue. ASL を調べて、DSD 内のリソースのインデックスを再確認し、ピン番号の昇順で GPIO リソースが指定されていることを確認します。Go over your ASL and double check resource indices in the DSD, and verify that GPIO resources are specified in increasing pin number order.

想定されているデバイスがユーザー モードに公開されていることを確認します。Verify that the expected devices are exposed to usermode

rhproxy が実行されると、ユーザー モードからアクセスできるデバイス インターフェイスが作成されています。Now that rhproxy is running, it should have created devices interfaces that can be accessed by usermode. いくつかのコマンド ライン ツールを使用してデバイスを列挙し、デバイスが存在していることを確認します。We will use several command line tools to enumerate devices and see that they're present.

複製、 https://github.com/ms-iot/samples リポジトリ、ビルド、 GpioTestToolI2cTestToolSpiTestTool 、およびMincomm サンプル。Clone the https://github.com/ms-iot/samples repository and build the GpioTestTool, I2cTestTool, SpiTestTool, and Mincomm samples. テスト対象デバイスにツールをコピーし、次のコマンドを使用してデバイスを列挙します。Copy the tools to your device under test and use the following commands to enumerate devices.

I2cTestTool.exe -list
SpiTestTool.exe -list
GpioTestTool.exe -list
MinComm.exe -list

デバイスとフレンドリ名の一覧が表示されます。You should see your devices and friendly names listed. 右側のデバイスとフレンドリ名が表示されない場合は、ASL を再確認してください。If you don't see the right devices and friendly names, double check your ASL.

コマンド ラインで各デバイスを確認するVerify each device on the command line

次の手順では、コマンド ライン ツールを使用して、デバイスを開き、操作します。The next step is to use the command line tools to open and interact with the devices.

I2CTestTool の例:I2CTestTool example:

I2cTestTool.exe 0x55 I2C1
> write {1 2 3}
> read 3
> writeread {1 2 3} 3

SpiTestTool の例:SpiTestTool example:

SpiTestTool.exe -n SPI1
> write {1 2 3}
> read 3

GpioTestTool の例:GpioTestTool example:

GpioTestTool.exe 12
> setdrivemode output
> write 0
> write 1
> setdrivemode input
> read
> interrupt on
> interrupt off

MinComm (シリアル) の例。MinComm (serial) example. 実行する前に Tx に Rx を接続します。Connect Rx to Tx before running:

MinComm "\\?\ACPI#FSCL0007#3#{86e0d1e0-8089-11d0-9ce4-08003e301f73}\0000000000000006"
(type characters and see them echoed back)

UWP アプリから各デバイスを確認するVerify each device from a UWP app

次のサンプルを使用して、UWP からデバイスが動作することを確認します。Use the following samples to validate that devices work from UWP.

サンプルSample リンクLink
IoT-GPIOIoT-GPIO https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/IoT-GPIO
IoT-I2CIoT-I2C https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/IoT-I2C
IoT-SPIIoT-SPI https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/IoT-SPI
CustomSerialDeviceAccessCustomSerialDeviceAccess https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CustomSerialDeviceAccess

HLK テストの実行Run the HLK Tests

Hardware Lab Kit (HLK) をダウンロードします。Download the Hardware Lab Kit (HLK). 以下のテストが用意されています。The following tests are availble:

HLK マネージャーで rhproxy デバイス ノードを選択すると、適用できるテストが自動的に選択されます。When you select the rhproxy device node in HLK manager, the applicable tests will automatically be selected.

HLK マネージャーで、[Resource Hub Proxy device] を選択します。In the HLK manager, select “Resource Hub Proxy device”:

HLK マネージャーのスクリーンショット

その後、[テスト] タブをクリックし、I2C WinRT、Gpio WinRT、Spi WinRT のテストを選択します。Then click the Tests tab, and select I2C WinRT, Gpio WinRT, and Spi WinRT tests.

HLK マネージャーのスクリーンショット

[選択したテストの実行] をクリックします。Click Run Selected. 各テストに関するその他のドキュメントは、テストを右クリックして [テストの説明] をクリックすることで利用できます。Further documentation on each test is available by right clicking on the test and clicking “Test Description.”

参考資料Resources

宛先Destination リンクLink
ACPI 5.0 の仕様ACPI 5.0 specification http://acpi.info/spec.htm
Asl.exe (Microsoft ASL Compiler)Asl.exe (Microsoft ASL Compiler) https://msdn.microsoft.com/library/windows/hardware/dn551195.aspx
Windows.Devices.GpioWindows.Devices.Gpio https://msdn.microsoft.com/library/windows/apps/windows.devices.gpio.aspx
Windows.Devices.I2cWindows.Devices.I2c https://msdn.microsoft.com/library/windows/apps/windows.devices.i2c.aspx
Windows.Devices.SpiWindows.Devices.Spi https://msdn.microsoft.com/library/windows/apps/windows.devices.spi.aspx
Windows.Devices.SerialCommunicationWindows.Devices.SerialCommunication https://msdn.microsoft.com/library/windows/apps/windows.devices.serialcommunication.aspx
Test Authoring and Execution Framework (TAEF)Test Authoring and Execution Framework (TAEF) https://msdn.microsoft.com/library/windows/hardware/hh439725.aspx
SpbCxSpbCx https://msdn.microsoft.com/library/windows/hardware/hh450906.aspx
GpioClxGpioClx https://msdn.microsoft.com/library/windows/hardware/hh439508.aspx
SerCxSerCx https://msdn.microsoft.com/library/windows/hardware/ff546939.aspx
MITT I2C テストMITT I2C Tests https://msdn.microsoft.com/library/windows/hardware/dn919852.aspx
GpioTestToolGpioTestTool https://developer.microsoft.com/windows/iot/samples/GPIOTestTool
I2cTestToolI2cTestTool https://developer.microsoft.com/windows/iot/samples/I2cTestTool
SpiTestToolSpiTestTool https://developer.microsoft.com/windows/iot/samples/spitesttool
MinComm (シリアル)MinComm (Serial) https://github.com/ms-iot/samples/tree/develop/MinComm
ハードウェア ラボ キット (HLK)Hardware Lab Kit (HLK) https://msdn.microsoft.com/library/windows/hardware/dn930814.aspx

付録Apendix

付録 A - Raspberry Pi ASL の一覧Appendix A - Raspberry Pi ASL Listing

ヘッダーのピン配列: https://developer.microsoft.com/windows/iot/samples/PinMappingsRPi2Header pinout: https://developer.microsoft.com/windows/iot/samples/PinMappingsRPi2

DefinitionBlock ("ACPITABL.dat", "SSDT", 1, "MSFT", "RHPROXY", 1)
{

    Scope (\_SB)
    {
        //
        // RHProxy Device Node to enable WinRT API
        //
        Device(RHPX)
        {
            Name(_HID, "MSFT8000")
            Name(_CID, "MSFT8000")
            Name(_UID, 1)

            Name(_CRS, ResourceTemplate()
            {
                // Index 0
                SPISerialBus(              // SCKL - GPIO 11 - Pin 23
                                           // MOSI - GPIO 10 - Pin 19
                                           // MISO - GPIO 9  - Pin 21
                                           // CE0  - GPIO 8  - Pin 24
                    0,                     // Device selection (CE0)
                    PolarityLow,           // Device selection polarity
                    FourWireMode,          // wiremode
                    0,                     // databit len: placeholder
                    ControllerInitiated,   // slave mode
                    0,                     // connection speed: placeholder
                    ClockPolarityLow,      // clock polarity: placeholder
                    ClockPhaseFirst,       // clock phase: placeholder
                    "\\_SB.SPI0",          // ResourceSource: SPI bus controller name
                    0,                     // ResourceSourceIndex
                                           // Resource usage
                    )                      // Vendor Data

                // Index 1
                SPISerialBus(              // SCKL - GPIO 11 - Pin 23
                                           // MOSI - GPIO 10 - Pin 19
                                           // MISO - GPIO 9  - Pin 21
                                           // CE1  - GPIO 7  - Pin 26
                    1,                     // Device selection (CE1)
                    PolarityLow,           // Device selection polarity
                    FourWireMode,          // wiremode
                    0,                     // databit len: placeholder
                    ControllerInitiated,   // slave mode
                    0,                     // connection speed: placeholder
                    ClockPolarityLow,      // clock polarity: placeholder
                    ClockPhaseFirst,       // clock phase: placeholder
                    "\\_SB.SPI0",          // ResourceSource: SPI bus controller name
                    0,                     // ResourceSourceIndex
                                           // Resource usage
                    )                      // Vendor Data

                // Index 2
                SPISerialBus(              // SCKL - GPIO 21 - Pin 40
                                           // MOSI - GPIO 20 - Pin 38
                                           // MISO - GPIO 19 - Pin 35
                                           // CE1  - GPIO 17 - Pin 11
                    1,                     // Device selection (CE1)
                    PolarityLow,           // Device selection polarity
                    FourWireMode,          // wiremode
                    0,                     // databit len: placeholder
                    ControllerInitiated,   // slave mode
                    0,                     // connection speed: placeholder
                    ClockPolarityLow,      // clock polarity: placeholder
                    ClockPhaseFirst,       // clock phase: placeholder
                    "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
                    0,                     // ResourceSourceIndex
                                           // Resource usage
                    )                      // Vendor Data
                // Index 3
                I2CSerialBus(              // Pin 3 (GPIO2, SDA1), 5 (GPIO3, SCL1)
                    0xFFFF,                // SlaveAddress: placeholder
                    ,                      // SlaveMode: default to ControllerInitiated
                    0,                     // ConnectionSpeed: placeholder
                    ,                      // Addressing Mode: placeholder
                    "\\_SB.I2C1",          // ResourceSource: I2C bus controller name
                    ,
                    ,
                    )                      // VendorData

                // Index 4 - GPIO 4 -
                GpioIO(Shared, PullUp, , , , "\\_SB.GPI0", , , , ) { 4 }
                GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GPI0",) { 4 }
                // Index 6 - GPIO 5 -
                GpioIO(Shared, PullUp, , , , "\\_SB.GPI0", , , , ) { 5 }
                GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GPI0",) { 5 }
                // Index 8 - GPIO 6 -
                GpioIO(Shared, PullUp, , , , "\\_SB.GPI0", , , , ) { 6 }
                GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GPI0",) { 6 }
                // Index 10 - GPIO 12 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 12 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 12 }
                // Index 12 - GPIO 13 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 13 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 13 }
                // Index 14 - GPIO 16 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 16 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 16 }
                // Index 16 - GPIO 18 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 18 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 18 }
                // Index 18 - GPIO 22 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 22 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 22 }
                // Index 20 - GPIO 23 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 23 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 23 }
                // Index 22 - GPIO 24 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 24 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 24 }
                // Index 24 - GPIO 25 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 25 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 25 }
                // Index 26 - GPIO 26 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 26 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 26 }
                // Index 28 - GPIO 27 -
                GpioIO(Shared, PullDown, , , , "\\_SB.GPI0", , , , ) { 27 }
                GpioInt(Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GPI0",) { 27 }
                // Index 30 - GPIO 35 -
                GpioIO(Shared, PullUp, , , , "\\_SB.GPI0", , , , ) { 35 }
                GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GPI0",) { 35 }
                // Index 32 - GPIO 47 -
                GpioIO(Shared, PullUp, , , , "\\_SB.GPI0", , , , ) { 47 }
                GpioInt(Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GPI0",) { 47 }
            })

            Name(_DSD, Package()
            {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package()
                {
                    // Reference http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md
                    // SPI 0
                    Package(2) { "bus-SPI-SPI0", Package() { 0, 1 }},                       // Index 0 & 1
                    Package(2) { "SPI0-MinClockInHz", 7629 },                               // 7629 Hz
                    Package(2) { "SPI0-MaxClockInHz", 125000000 },                          // 125 MHz
                    Package(2) { "SPI0-SupportedDataBitLengths", Package() { 8 }},          // Data Bit Length
                    // SPI 1
                    Package(2) { "bus-SPI-SPI1", Package() { 2 }},                          // Index 2
                    Package(2) { "SPI1-MinClockInHz", 30518 },                              // 30518 Hz
                    Package(2) { "SPI1-MaxClockInHz", 125000000 },                          // 125 MHz
                    Package(2) { "SPI1-SupportedDataBitLengths", Package() { 8 }},          // Data Bit Length
                    // I2C1
                    Package(2) { "bus-I2C-I2C1", Package() { 3 }},
                    // GPIO Pin Count and supported drive modes
                    Package (2) { "GPIO-PinCount", 54 },
                    Package (2) { "GPIO-UseDescriptorPinNumbers", 1 },
                    Package (2) { "GPIO-SupportedDriveModes", 0xf },                        // InputHighImpedance, InputPullUp, InputPullDown, OutputCmos
                }
            })
        }
    }
}

付録 B - MinnowBoardMax ASL の一覧Appendix B - MinnowBoardMax ASL Listing

ヘッダーのピン配列: https://developer.microsoft.com/windows/iot/samples/PinMappingsMBMHeader pinout: https://developer.microsoft.com/windows/iot/samples/PinMappingsMBM

DefinitionBlock ("ACPITABL.dat", "SSDT", 1, "MSFT", "RHPROXY", 1)
{
    Scope (\_SB)
    {
        Device(RHPX)
        {
            Name(_HID, "MSFT8000")
            Name(_CID, "MSFT8000")
            Name(_UID, 1)

            Name(_CRS, ResourceTemplate()
            {
                // Index 0
                SPISerialBus(            // Pin 5, 7, 9 , 11 of JP1 for SIO_SPI
                    1,                     // Device selection
                    PolarityLow,           // Device selection polarity
                    FourWireMode,          // wiremode
                    8,                     // databit len
                    ControllerInitiated,   // slave mode
                    8000000,               // Connection speed
                    ClockPolarityLow,      // Clock polarity
                    ClockPhaseSecond,      // clock phase
                    "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
                    0,                     // ResourceSourceIndex
                    ResourceConsumer,      // Resource usage
                    JSPI,                  // DescriptorName: creates name for offset of resource descriptor
                    )                      // Vendor Data

                // Index 1
                I2CSerialBus(            // Pin 13, 15 of JP1, for SIO_I2C5 (signal)
                    0xFF,                  // SlaveAddress: bus address
                    ,                      // SlaveMode: default to ControllerInitiated
                    400000,                // ConnectionSpeed: in Hz
                    ,                      // Addressing Mode: default to 7 bit
                    "\\_SB.I2C6",          // ResourceSource: I2C bus controller name (For MinnowBoard Max, hardware I2C5(0-based) is reported as ACPI I2C6(1-based))
                    ,
                    ,
                    JI2C,                  // Descriptor Name: creates name for offset of resource descriptor
                    )                      // VendorData

                // Index 2
                UARTSerialBus(           // Pin 17, 19 of JP1, for SIO_UART2
                    115200,                // InitialBaudRate: in bits ber second
                    ,                      // BitsPerByte: default to 8 bits
                    ,                      // StopBits: Defaults to one bit
                    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
                    ,                      // IsBigEndian: default to LittleEndian
                    ,                      // Parity: Defaults to no parity
                    ,                      // FlowControl: Defaults to no flow control
                    32,                    // ReceiveBufferSize
                    32,                    // TransmitBufferSize
                    "\\_SB.URT2",          // ResourceSource: UART bus controller name
                    ,
                    ,
                    UAR2,                  // DescriptorName: creates name for offset of resource descriptor
                    )

                // Index 3
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {0}  // Pin 21 of JP1 (GPIO_S5[00])
                // Index 4
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {0}

                // Index 5
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {1}  // Pin 23 of JP1 (GPIO_S5[01])
                // Index 6
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {1}

                // Index 7
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {2}  // Pin 25 of JP1 (GPIO_S5[02])
                // Index 8
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {2}

                // Index 9
                UARTSerialBus(           // Pin 6, 8, 10, 12 of JP1, for SIO_UART1
                    115200,                // InitialBaudRate: in bits ber second
                    ,                      // BitsPerByte: default to 8 bits
                    ,                      // StopBits: Defaults to one bit
                    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
                    ,                      // IsBigEndian: default to LittleEndian
                    ,                      // Parity: Defaults to no parity
                    FlowControlHardware,   // FlowControl: Defaults to no flow control
                    32,                    // ReceiveBufferSize
                    32,                    // TransmitBufferSize
                    "\\_SB.URT1",          // ResourceSource: UART bus controller name
                    ,
                    ,
                    UAR1,              // DescriptorName: creates name for offset of resource descriptor
                    )

                // Index 10
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {62}  // Pin 14 of JP1 (GPIO_SC[62])
                // Index 11
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {62}

                // Index 12
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {63}  // Pin 16 of JP1 (GPIO_SC[63])
                // Index 13
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {63}

                // Index 14
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {65}  // Pin 18 of JP1 (GPIO_SC[65])
                // Index 15
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {65}

                // Index 16
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {64}  // Pin 20 of JP1 (GPIO_SC[64])
                // Index 17
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {64}

                // Index 18
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {94}  // Pin 22 of JP1 (GPIO_SC[94])
                // Index 19
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {94}

                // Index 20
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {95}  // Pin 24 of JP1 (GPIO_SC[95])
                // Index 21
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {95}

                // Index 22
                GpioIo (Shared, PullNone, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {54}  // Pin 26 of JP1 (GPIO_SC[54])
                // Index 23
                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {54}
            })

            Name(_DSD, Package()
            {
                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                Package()
                {
                    // SPI Mapping
                    Package(2) { "bus-SPI-SPI0", Package() { 0 }},

                    Package(2) { "SPI0-MinClockInHz", 100000 },
                    Package(2) { "SPI0-MaxClockInHz", 15000000 },
                    // SupportedDataBitLengths takes a list of support data bit length
                    // Example : Package(2) { "SPI0-SupportedDataBitLengths", Package() { 8, 7, 16 }},
                    Package(2) { "SPI0-SupportedDataBitLengths", Package() { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }},
                     // I2C Mapping
                    Package(2) { "bus-I2C-I2C5", Package() { 1 }},
                    // UART Mapping
                    Package(2) { "bus-UART-UART2", Package() { 2 }},
                    Package(2) { "bus-UART-UART1", Package() { 9 }},
                }
            })
        }
    }
}

付録 C - GPIO リソースを生成するためのサンプル Powershell スクリプトAppendix C - Sample Powershell script to generate GPIO resources

次のスクリプトを使って、Raspberry Pi の GPIO リソース宣言を生成することができます。The following script can be used to generate the GPIO resource declarations for Raspberry Pi:

$pins = @(
    @{PinNumber=4;PullConfig='PullUp'},
    @{PinNumber=5;PullConfig='PullUp'},
    @{PinNumber=6;PullConfig='PullUp'},
    @{PinNumber=12;PullConfig='PullDown'},
    @{PinNumber=13;PullConfig='PullDown'},
    @{PinNumber=16;PullConfig='PullDown'},
    @{PinNumber=18;PullConfig='PullDown'},
    @{PinNumber=22;PullConfig='PullDown'},
    @{PinNumber=23;PullConfig='PullDown'},
    @{PinNumber=24;PullConfig='PullDown'},
    @{PinNumber=25;PullConfig='PullDown'},
    @{PinNumber=26;PullConfig='PullDown'},
    @{PinNumber=27;PullConfig='PullDown'},
    @{PinNumber=35;PullConfig='PullUp'},
    @{PinNumber=47;PullConfig='PullUp'})

# generate the resources
$FIRST_RESOURCE_INDEX = 4
$resourceIndex = $FIRST_RESOURCE_INDEX
$pins | % {
    $a = @"
// Index $resourceIndex - GPIO $($_.PinNumber) - $($_.Name)
GpioIO(Shared, $($_.PullConfig), , , , "\\_SB.GPI0", , , , ) { $($_.PinNumber) }
GpioInt(Edge, ActiveBoth, Shared, $($_.PullConfig), 0, "\\_SB.GPI0",) { $($_.PinNumber) }
"@
    Write-Host $a
    $resourceIndex += 2;
}