SpbTestTool

Summary

The SpbTestTool sample serves two purposes.  One, it demonstrates how to open a handle to the SPB controller, use the SPB interface from a KMDF driver, and employ GPIO passive-level interrupts.  Two, it allows for communication with a peripheral using SPB commands to aide in debugging.

This sample is incomplete as a driver and merely demonstrates use of the SPB API and GPIO interrupts.  It is not intended for use in a production environment.

Building the Sample

Peripheral driver

1.       Navigate to src\SPB\SpbTestTool\sys and launch the vcxproj file

2.       Modify SpbTestTool.inx

a.       Replace ACPI\SpbTestTool with appropriate peripheral HWID

b.      Set the “ConnectInterrupt registery” setting to 1 to connect the first interrupt resource found, otherwise leave at 0 to leave disconnected.  See SpbTestTool_AddReg section.

3.       Build the project in Visual Studio

a.       Produces SpbTestTool.inf and SpbTestTool.sys

Application

1.       Navigate to src\SPB\SpbTestTool\exe and launch the vcxproj file

2.       Build the project in Visual Studio

a.       Produces SpbTestTool.exe

Installation

To install the SpbTestTool driver:

1.       Ensure that the driver builds without errors

2.       Copy the SYS and INF files to a separate folder

3.       Run devcon.exe.  You can find this program in the tools\devcon folder where you installed the WDK.  Type the following command in the command window.

a.       devcon.exe update SpbTestTool.inf ACPI\<hwid>

Code Tour

The following are relevant functions in the SpbTestTool peripheral for using the SPB interface from a KMDF driver.

Function

Description

OnPrepareHardware

Traverses the driver’s start resources and caches the connection ID of the I2C or SPI resource.  This ID will be used to open the SPB controller later on.

SpbPeripheralOpen

Opens a handle to the underlying SPB controller via the resource hub.  This allows the peripheral driver to be developed without any underlying knowledge of the platform or hardware connections.  Instead, the dependency between controller and peripheral is described in ACPI.

SpbPeripheralClose

Closes the handle to the SPB controller.

SpbPeripheralLock

Sends IOCTL_SPB_LOCK_CONTROLLER to the SPB controller to lock the bus for exclusive access by this peripheral.

SpbPeripheralUnlock

Sends IOCTL_SPB_UNLOCK_CONTROLLER to the SPB controller to unlock the bus from exclusive access by this peripheral.

SpbPeripheralLockConnection

Sends IOCTL_SPB_LOCK_CONNECTION to the SPB controller to lock the shared connection for exclusive access by this target (file handle).

SpbPeripheralUnlockConnection

Sends IOCTL_SPB_UNLOCK_CONNECTION to the SPB controller to unlock the shared connection from exclusive access by this target (file handle).

SpbPeripheralRead

Sends a read request to the SPB controller.

SpbPeripheralWrite

Sends a write request to the SPB controller.

SpbPeripheralWriteRead

Builds a write-read sequence and sends IOCTL_SPB_EXECUTE_SEQUENCE to the SPB controller.

SpbPeripheralFullDuplex

Builds a full duplex IO and sends IOCTL_SPB_FULL_DUPLEX to the SPB controller.

SpbPeripheralOnComplete

Completion callback for all IO.

 

The following are relevant functions in the SpbTestTool peripheral for managing GPIO passive-level interrupts from a KMDF driver.

Function

Description

OnPrepareHardware

Traverses the driver’s start resources. If “ConnectInterrupt” is set to 1 in the registry, the driver connects the first interrupt resource found and registers an interrupt service routine.

OnInterruptIsr

The interrupt service routine, which has been configured to run at passive-level.  Doing so enables the driver to acknowledge or quiesce the interrupt using the SPB interface, which cannot be called at DIRQL.

 

Typically a driver will clear the hardware interrupt and save any volatile information in its ISR, and then it will queue a workitem to continue processing.  Our sample driver instead notifies the SpbTestTool app that an interrupt has occurred and calls KeWaitForSingleObject to wait until the interrupt is handled before returning. A ‘real’ driver should never stall in the ISR like this.

SpbPeripheralWaitOnInterrupt

Called to pend a WaitOnInterrupt request in the driver, which will be completed when the next interrupt occurs.

SpbPeripheralInterruptNotify

Completes an outstanding WaitOnInterrupt request to inform the SpbTestTool app that an interrupt has occurred.

SpbPeripheralSignalInterrupt

Notifies the interrupt service routine that the interrupt has been handled and the ISR should return.

Application Walkthrough

Launching the app

To launch the SpbTestTool application:

1.       Navigate to the directory with SpbTestTool.exe

2.       Type the following command in the command window:

a.       SpbTestTool.exe

3.       An alternate peripheral driver path can also be used.  Note, this driver must implement the private SpbTestTool interface

a.       SpbTestTool.exe /p \\.\<alternate_path>

4.       An input script can used instead of an interactive prompt.  The format is one command per line.  See below for commands.

a.       SpbTestTool.exe /i <script.txt>

Executing commands

The application will loop indefinitely waiting for one of the following commands.  The commands are translated to the appropriate SPB API action without any state tracking in the driver.  Transfer status, buffers, and error codes are returned as necessary.  Type ‘help’ at any time to display this list.  Press Ctrl-C at any time to cancel the current command and exit the application.

Command

Description

open

Open handle to SPB controller

close

Close handle to SPB controller

lock

Lock the bus for exclusive access

unlock

Unlock the bus

lockconn

Lock the shared connection for exclusive access. This primitive is used to synchronize with op-region accesses by firmware.

unlockconn

Unlock the shared connection

write {}

Write byte array to peripherl

  > write {01, 02, 03}

read <numBytes>

Read <numBytes> from peripheral

  > read 5

writeread {} <numBytes>

Atomically write byte array to peripheral and read <numBytes> back

  > writeread {01, 02, 03} 5

fullduplex {} <numBytes>

Simultaneously write byte array to peripheral and read <numBytes> back

  > full duplex {01, 02, 03} 5

signal

Inform the SpbTestTool driver that the interrupt has been handled

help

Display the list of supported commands

Ctrl-C

Press Ctrl-C at any time to cancel the outstanding command and exit the application.

File Manifest

Peripheral driver (spbtesttool.sys)

File

Description

driver.h, driver.cpp

DriverEntry and Events on the Driver Object.

device.h, device.cpp

Events on the Device Object, and read, write, and IOCTLs from the SpbTestTool application. Implements the driver’s interrupt service routine.

internal.h

Common includes and typedefs

makefile

Redirects to the real makefile that is shared  by all components of the WDK

makefile.inc

Defines custom build actions.  Includes the conversion of the .INX file into a .INF file

peripheral.h, peripheral.cpp

Reflection of the SpbTestTool IOCTLs to the SPB API, including opening the controller via the resource hub and using lock, unlock, read, write, and sequence

resource.rc

Resource descriptor file used for versioning

sources

Lists source files and build options

sources.dep

Defines build dependencies

spbtesttool.asl

Sample ASL file for a peripheral device node. It declares I2C and GPIO interrupt resources. Note each macro specifies an ACPI path to describe direct dependencies.

spbtesttool.h

Private SpbTestTool IOCTLs for use between the application and peripheral driver, and driver path names

spbtesttool.inx

Describes the installation of the driver.  The build process converts this into a .INF

trace.h

Sets up WPP tracing

Application (spbtesttool.exe)

File

Description

command.h, command.cpp

Classes respresenting each of the SpbTestTool commands.  See Executing commands above

internal.h

Common includes and function definitions

main.cpp

Application entry point, input parsing, and main execution loop. Also contains the interrupt notification thread.

makefile

Redirects to the real makefile that is shared by all components of the WDK

sources

Lists source files and build options

util.cpp

Helper functions

 

Copyright © Microsoft Corporation.  All Rights Reserved.