Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Een GPIO I/O-resource is een set van een of meer GPIO-pinnen die zijn geconfigureerd als gegevensinvoer of gegevensuitvoer. Het stuurprogramma voor een randapparaat dat fysiek verbinding maakt met deze pinnen verkrijgt de bijbehorende GPIO I/O-resource van het besturingssysteem. Het stuurprogramma van het randapparaat opent een verbinding met de GPIO-pinnen in deze resource en verzendt I/O-aanvragen naar de ingang die deze verbinding vertegenwoordigt.
In het volgende codevoorbeeld ziet u hoe het KMDF-stuurprogramma (Kernel Mode Driver Framework) voor een randapparaat een beschrijving kan verkrijgen van de GPIO I/O-resource die de Plug and Play-manager (PnP) aan het stuurprogramma heeft toegewezen.
NTSTATUS
EvtDevicePrepareHardware(
_In_ WDFDEVICE Device,
_In_ WDFCMRESLIST ResourcesRaw,
_In_ WDFCMRESLIST ResourcesTranslated
)
{
int ResourceCount, Index;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
XYZ_DEVICE_CONTEXT *DeviceExtension;
...
DeviceExtension = XyzDrvGetDeviceExtension(Device);
ResourceCount = WdfCmResourceListGetCount(ResourcesTranslated);
for (Index = 0; Index < ResourceCount; Index += 1) {
Descriptor = WdfCmResourceListGetDescriptor(ResourcesTranslated, Index);
switch (Descriptor->Type) {
//
// GPIO I/O descriptors
//
case CmResourceTypeConnection:
//
// Check against expected connection type.
//
if ((Descriptor->u.Connection.Class == CM_RESOURCE_CONNECTION_CLASS_GPIO) &&
(Descriptor->u.Connection.Type == CM_RESOURCE_CONNECTION_TYPE_GPIO_IO)) {
DeviceExtension->ConnectionId.LowPart = Descriptor->u.Connection.IdLowPart;
DeviceExtension->ConnectionId.HighPart = Descriptor->u.Connection.IdHighPart;
...
}
In het voorgaande codevoorbeeld is de DeviceExtension
variabele een aanwijzer naar de apparaatcontext voor het randapparaat. De XyzDrvGetDeviceExtension
functie, die deze apparaatcontext ophaalt, wordt geïmplementeerd door het stuurprogramma van het randapparaat. Dit stuurprogramma heeft eerder de callbackfunctie EvtDevicePrepareHardware geregistreerd door de methode WdfDeviceInitSetPnpPowerEventCallbacks aan te roepen.
In het volgende codevoorbeeld ziet u hoe het stuurprogramma van het randapparaat de GPIO-resourcebeschrijving kan gebruiken die in het vorige codevoorbeeld is verkregen om een WDFIOTARGET-ingang te openen voor de GPIO I/O-resource van het stuurprogramma.
NTSTATUS IoRoutine(WDFDEVICE Device, BOOLEAN ReadOperation)
{
WDFIOTARGET IoTarget;
XYZ_DEVICE_CONTEXT *DeviceExtension;
UNICODE_STRING ReadString;
WCHAR ReadStringBuffer[100];
BOOL DesiredAccess;
NTSTATUS Status;
WDF_OBJECT_ATTRIBUTES ObjectAttributes;
WDF_IO_TARGET_OPEN_PARAMS OpenParams
DeviceExtension = XyzDrvGetDeviceExtension(Device);
RtlInitEmptyUnicodeString(&ReadString,
ReadStringBuffer,
sizeof(ReadStringBuffer));
Status = RESOURCE_HUB_CREATE_PATH_FROM_ID(&ReadString,
DeviceExtension->ConnectionId.LowPart,
DeviceExtension->ConnectionId.HighPart);
NT_ASSERT(NT_SUCCESS(Status));
WDF_OBJECT_ATTRIBUTES_INIT(&ObjectAttributes);
ObjectAttributes.ParentObject = Device;
Status = WdfIoTargetCreate(Device, &ObjectAttributes, &IoTarget);
if (!NT_SUCCESS(Status)) {
goto IoErrorEnd;
}
if (ReadOperation != FALSE) {
DesiredAccess = GENERIC_READ;
} else {
DesiredAccess = GENERIC_WRITE;
}
WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(&OpenParams, ReadString, DesiredAccess);
Status = WdfIoTargetOpen(IoTarget, &OpenParams);
if (!NT_SUCCESS(Status)) {
goto IoErrorEnd;
}
...
In het voorgaande codevoorbeeld is de Device
-variabele een WDFDEVICE-handle voor het raamwerkapparaatobject van het randapparaat. Met de functie RESOURCE_HUB_CREATE_PATH_FROM_ID wordt een tekenreeks gemaakt die de naam van de GPIO I/O-resource bevat. In het codevoorbeeld wordt deze tekenreeks gebruikt om de GPIO I/O-resource op naam te openen.
Nadat het stuurprogramma van het randapparaat een ingang heeft verkregen voor een GPIO I/O-resource, kan dit stuurprogramma I/O-besturingsaanvragen verzenden om gegevens van de GPIO-pinnen te lezen of te schrijven. Een stuurprogramma waarmee een GPIO I/O-resource voor leesbewerkingen wordt geopend , gebruikt IOCTL_GPIO_READ_PINS I/O-beheeraanvragen om gegevens van de pinnen in de resource te lezen. Een stuurprogramma waarmee een GPIO I/O-resource voor schrijfbewerkingen wordt geopend, maakt gebruik van IOCTL_GPIO_WRITE_PINS I/O-beheeraanvragen voor het schrijven van gegevens naar de pinnen in de resource. In het volgende codevoorbeeld ziet u hoe u een GPIO-lees- of schrijfbewerking uitvoert.
WDF_OBJECT_ATTRIBUTES RequestAttributes;
WDF_OBJECT_ATTRIBUTES Attributes;
WDF_REQUEST_SEND_OPTIONS SendOptions;
WDFREQUEST IoctlRequest;
WDFIOTARGET IoTarget;
WDFMEMORY WdfMemory;
NTSTATUS Status;
WDF_OBJECT_ATTRIBUTES_INIT(&RequestAttributes);
Status = WdfRequestCreate(&RequestAttributes, IoTarget, &IoctlRequest);
if (!NT_SUCCESS(Status)) {
goto RwErrorExit;
}
//
// Set up a WDF memory object for the IOCTL request.
//
WDF_OBJECT_ATTRIBUTES_INIT(&Attributes);
Attributes.ParentObject = IoctlRequest;
Status = WdfMemoryCreatePreallocated(&Attributes, Data, Size, &WdfMemory);
if (!NT_SUCCESS(Status)) {
goto RwErrorExit;
}
//
// Format the request.
//
if (ReadOperation != FALSE) {
Status = WdfIoTargetFormatRequestForIoctl(IoTarget,
IoctlRequest,
IOCTL_GPIO_READ_PINS,
NULL,
0,
WdfMemory,
0);
} else {
Status = WdfIoTargetFormatRequestForIoctl(IoTarget,
IoctlRequest,
IOCTL_GPIO_WRITE_PINS,
WdfMemory,
0,
WdfMemory,
0);
}
if (!NT_SUCCESS(Status)) {
goto RwErrorExit;
}
//
// Send the request synchronously (with a 60-second time-out).
//
WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions,
WDF_REL_TIMEOUT_IN_SEC(60));
Status = WdfRequestAllocateTimer(IoctlRequest);
if (!NT_SUCCESS(Status)) {
goto RwErrorExit;
}
if (!WdfRequestSend(IoctlRequest, IoTarget, &SendOptions)) {
Status = WdfRequestGetStatus(IoctlRequest);
}
...
In het voorgaande codevoorbeeld Data
is een aanwijzer naar een gegevensbuffer, Size
is de grootte, in bytes, van deze gegevensbuffer en ReadOperation
wordt aangegeven of de aangevraagde bewerking een leesbewerking (WAAR) of een schrijfbewerking (ONWAAR) is.
Voor meer informatie
Voor meer informatie over IOCTL_GPIO_READ_PINS-aanvragen, waaronder de toewijzing van invoerpinnen aan de bits in de uitvoerbuffer van de aanvraag, zie IOCTL_GPIO_READ_PINS. Zie IOCTL_GPIO_WRITE_PINS voor meer informatie over IOCTL_GPIO_WRITE_PINS verzoeken, waaronder de indeling van de bits in de invoerbuffer van het verzoek naar de gegevensuitvoerpennen.
Voor een voorbeeldstuurprogramma dat laat zien hoe u een GPIO-randapparaatstuurprogramma schrijft dat wordt uitgevoerd in de kernelmodus, raadpleegt u het SimDevice-voorbeeldstuurprogramma in de verzameling GPIO-voorbeeldstuurprogramma's op GitHub.