pciSample

更新时间:2024-01-27 11:09:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Dirs. DIRS= sys

Sys:

/**---------------------------------------------------------------------------------------------------**/ Device.c

#include \

#ifdef ALLOC_PRAGMA

#pragma alloc_text(PAGE, PCISample_EvtDeviceAdd) #pragma alloc_text(PAGE, InitializeDMA)

#pragma alloc_text(PAGE, PCISample_EvtDevicePrepareHardware) #pragma alloc_text(PAGE, PCISample_EvtDeviceReleaseHardware) #endif

NTSTATUS

PCISample_EvtDeviceAdd(

IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit ) {

NTSTATUS status;

WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES deviceAttributes; WDFDEVICE device; PDEVICE_CONTEXT pDeviceContext; WDF_INTERRUPT_CONFIG interruptConfig; WDF_IO_QUEUE_CONFIG ioQueueConfig;

PAGED_CODE(); //采用WdfDeviceIoDirect方式

WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect); //初始化即插即用和电源管理例程配置结构

WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); //设置即插即用基本例程

pnpPowerCallbacks.EvtDevicePrepareHardware = PCISample_EvtDevicePrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = PCISample_EvtDeviceReleaseHardware;

//注册即插即用和电源管理例程

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); //

// Set WDFDEVICE synchronization scope. By opting for device level // synchronization scope, all the queue and timer callbacks are // synchronized with the device-level spinlock. //

deviceAttributes.SynchronizationScope = WdfSynchronizationScopeDevice;

status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); if (!NT_SUCCESS(status)) { return status; }

pDeviceContext = GetDeviceContext(device); //设置中断服务例程和延迟过程调用

WDF_INTERRUPT_CONFIG_INIT(&interruptConfig,

PCISample_EvtInterruptIsr, PCISample_EvtInterruptDpc); //创建中断对象

status = WdfInterruptCreate(device,

&interruptConfig,

WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext->Interrupt); if (!NT_SUCCESS (status)) { return status; }

status = InitializeDMA(device);

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

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchSequential);

ioQueueConfig.EvtIoWrite = PCISample_EvtIoWrite; ioQueueConfig.EvtIoRead = PCISample_EvtIoRead;

status = WdfIoQueueCreate(device, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, NULL);

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

status = WdfDeviceCreateDeviceInterface(device, (LPGUID)&PCISample_DEVINTERFACE_GUID, NULL); if (!NT_SUCCESS(status)) { }

return status; }

NTSTATUS InitializeDMA(

IN WDFDEVICE Device ) {

NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; WDF_DMA_ENABLER_CONFIG dmaConfig;

PAGED_CODE();

pDeviceContext = GetDeviceContext(Device);

//

// DMA_TRANSFER_ELEMENTS must be 16-byte aligned //

//设置DMA数据缓冲区地址边界:16字节对齐

WdfDeviceSetAlignmentRequirement( Device, FILE_OCTA_ALIGNMENT );

//

// Create a new DMA Enabler instance. // //创建一个DMA适配器 WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig, WdfDmaProfilePacket, MAXNLEN ); status = WdfDmaEnablerCreate( Device,

&dmaConfig,

WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext->DmaEnabler ); if (!NT_SUCCESS (status)) { DbgPrint(\ return status; } // // Create a new DmaTransaction. // //创建一个DMA传输 status = WdfDmaTransactionCreate( pDeviceContext->DmaEnabler,

WDF_NO_OBJECT_ATTRIBUTES,

&pDeviceContext->DmaTransaction ); if(!NT_SUCCESS(status)) { DbgPrint(\ }

return status; }

NTSTATUS

PCISample_EvtDevicePrepareHardware( IN WDFDEVICE Device,

IN WDFCMRESLIST ResourceList,

IN WDFCMRESLIST ResourceListTranslated ) {

PDEVICE_CONTEXT pDeviceContext; ULONG i; PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;

PAGED_CODE();

DbgPrint(\

pDeviceContext = GetDeviceContext(Device); pDeviceContext->MemBaseAddress = NULL;

//

// Parse the resource list and save the resource information. //

for (i=0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++) {

descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);

switch (descriptor->Type) {

case CmResourceTypeMemory: //MmMapIoSpace将物理地址转换成系统内核模式地址 pDeviceContext->MemBaseAddress = MmMapIoSpace( descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached); pDeviceContext->MemLength = descriptor->u.Memory.Length;

break;

default: break; }

}

DbgPrint(\

return STATUS_SUCCESS; }

NTSTATUS

PCISample_EvtDeviceReleaseHardware( IN WDFDEVICE Device,

IN WDFCMRESLIST ResourceListTranslated ) {

PDEVICE_CONTEXT pDeviceContext;

PAGED_CODE();

DbgPrint(\

pDeviceContext = GetDeviceContext(Device); if(pDeviceContext->MemBaseAddress) { //MmUnmapIoSpace解除物理地址与系统内核模式地址的关联 MmUnmapIoSpace(pDeviceContext->MemBaseAddress,

pDeviceContext->MemLength); pDeviceContext->MemBaseAddress = NULL; } DbgPrint(\ return STATUS_SUCCESS; }

/**---------------------------------------------------------------------------------------------------**/ driver.c

#include \

#ifdef ALLOC_PRAGMA

#pragma alloc_text(INIT, DriverEntry) #endif

NTSTATUS DriverEntry(

IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) {

WDF_DRIVER_CONFIG config; NTSTATUS status;

WDF_DRIVER_CONFIG_INIT(&config, PCISample_EvtDeviceAdd);

//

// Create a framework driver object to represent our driver. //

status = WdfDriverCreate( DriverObject, RegistryPath,

WDF_NO_OBJECT_ATTRIBUTES, // Driver Attributes &config, // Driver Config Info WDF_NO_HANDLE // hDriver );

return status; }

/*******************************************************************/ Makefile #

# DO NOT EDIT THIS FILE!!! Edit .\\sources. if you want to add a new source # file to this component. This file merely indirects to the real make file # that is shared by all the driver components of the Windows NT DDK #

!INCLUDE $(NTMAKEENV)\\makefile.def

/****************************************************************************/

Makefile.inc

_LNG=$(LANGUAGE) _INX=.

STAMP=stampinf -f $@ -a $(_BUILDARCH)

$(OBJ_PATH)\\$(O)\\$(INF_NAME).inf: $(_INX)\\$(INF_NAME).inx copy $(_INX)\\$(@B).inx $@ $(STAMP)

/****************************************************************************/ PCISample.INC

;Module Name: ; PCISample.INF ;

;Abstract:

; INF file for installing the Windows Driver Frameworks PCISample Driver ;

;Installation Notes:

; Using Devcon: Type \; ;--*/

[Version]

Signature=\Class=WDFBOOK

ClassGuid={EF1941A7-645B-4668-B05B-287D30169435}

Provider=%ProviderName%

DriverVer=12/28/2008,6.0.6000.16386

; ================= Class section =====================

[ClassInstall32]

Addreg=SampleClassReg

[SampleClassReg]

HKR,,,0,TviceClassName% HKR,,Icon,,-18

;***************************************** ; PCISample Install Section

;*****************************************

[Manufacturer]

%MfgName%=Standard,NTx86

; Following section is meant for Windows 2000 as it ; cannot parse decorated model sections [Standard] ;

; Hw Id is root\\PCISample ;

%PCISample.DeviceDesc%=PCISample_Device,

PCI\\VEN_5858&DEV_0002&SUBSYS_00000000&REV_01

; Decorated model section take precedence over undecorated ; ones on XP and later. [Standard.NTx86]

%PCISample.DeviceDesc%=PCISample_Device,

PCI\\VEN_5858&DEV_0002&SUBSYS_00000000&REV_01

[DestinationDirs]

PCISample_Files_Driver = 12

[PCISample_Device.NT]

CopyFiles=PCISample_Files_Driver

[PCISample_Files_Driver] PCISample.sys

;-------------- Service installation

[PCISample_Device.NT.Services]

AddService = PCISample,0x00000002, PCISample_AddService

; -------------- PCISample driver install sections [PCISample_AddService]

DisplayName = %PCISample.SVCDESC%

ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL ServiceBinary = %\\PCISample.sys ;

;--- WDF Coinstaller installation ---- ;

[DestinationDirs]

CoInstaller_CopyFiles = 11

[PCISample_Device.NT.CoInstallers] CopyFiles=CoInstaller_CopyFiles AddReg=CoInstaller_AddReg

[CoInstaller_CopyFiles] wdfcoinstaller01007.dll

[CoInstaller_AddReg]

HKR,,CoInstallers32,0x00010000, \

[PCISample_Device.NT.Wdf]

KmdfService = PCISample, PCISample_wdfsect

[PCISample_wdfsect] KmdfLibraryVersion = 1.7

[Strings]

ProviderName=\最新WDF设备驱动程序开发\MfgName=\武安河\

DeviceClassName=\范例\

PCISample.DeviceDesc = \

PCISample.SVCDESC = \

/************************************************************/

Private.h

#pragma warning(disable:4200) //

#pragma warning(disable:4201) // nameless struct/union

#pragma warning(disable:4214) // bit field types other than int

#include #include

#include \

#ifndef _H #define _H

//定义CY7C09449内部寄存器的偏移地址,请参阅CY7C09449文档资料 #define DMALBASE 0x04B0 #define DMAHBASE 0x04B4 #define DMASIZE 0x04B8 #define DMACTL 0x04BC #define HINT 0x04E4 #define RAM 0x4000

//MAXNLEN:DMA传输最大字节长度 #define MAXNLEN 0x1000

typedef struct _DEVICE_CONTEXT { WDFINTERRUPT Interrupt;

WDFDMAENABLER DmaEnabler;

WDFDMATRANSACTION DmaTransaction; PVOID MemBaseAddress; ULONG MemLength; } DEVICE_CONTEXT, *PDEVICE_CONTEXT;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)

NTSTATUS DriverEntry(

IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );

NTSTATUS

//下面几条语句设置DMA寄存器,读数据:FromDeviceToMemory //L地址

WRITE_REGISTER_USHORT((PUSHORT)(pREG+DMALBASE),RAM); //H地址

WRITE_REGISTER_ULONG((PULONG)(pREG+DMAHBASE),address);

//字节长度,0表示传输4字节,4表示传输8字节

WRITE_REGISTER_USHORT((PUSHORT)(pREG+DMASIZE),(USHORT)length-1);

//启动DMA传输 WRITE_REGISTER_USHORT((PUSHORT)(pREG+DMACTL),0x101);

// Release our interrupt spinlock WdfInterruptReleaseLock( pDeviceContext->Interrupt );

return TRUE; }

BOOLEAN

PCISample_EvtInterruptIsr(

IN WDFINTERRUPT Interrupt, IN ULONG MessageID ) {

PDEVICE_CONTEXT pDeviceContext; PUCHAR pREG; USHORT status; pDeviceContext = GetDeviceContext(WdfInterruptGetDevice(Interrupt)); pREG = pDeviceContext->MemBaseAddress;

//读取中断状态寄存器值

status = READ_REGISTER_USHORT((PUSHORT)(pREG+HINT)); if ((status & 0x020) == 0x020)

{ //判断是否为DMA传输结束中断 //若是,清除并禁止中断 WRITE_REGISTER_ULONG((PULONG)(pREG+HINT),0x3FF);

//

// Request the DPC to complete the transfer. //

WdfInterruptQueueDpcForIsr(Interrupt);

return TRUE; } else

return FALSE; // 不是由该设备产生的中断,返回FALSE }

VOID

PCISample_EvtInterruptDpc(

IN WDFINTERRUPT Interrupt, IN WDFOBJECT Device ) {

NTSTATUS status; WDFDEVICE device;

PDEVICE_CONTEXT pDeviceContext; WDFDMATRANSACTION dmaTransaction; BOOLEAN transactionComplete; WDFREQUEST request; size_t bytesTransferred;

pDeviceContext = GetDeviceContext(Device); dmaTransaction = pDeviceContext->DmaTransaction; request = WdfDmaTransactionGetRequest(dmaTransaction); // // Indicate this DMA operation has completed: // This may drive the transfer on the next packet if // there is still data to be transfered in the request. // transactionComplete =

WdfDmaTransactionDmaCompleted(dmaTransaction, &status); if (transactionComplete) {

}

//DMA传输字节数

bytesTransferred = WdfDmaTransactionGetBytesTransferred(dmaTransaction); //终止传输

WdfDmaTransactionRelease(dmaTransaction);

WdfRequestCompleteWithInformation(request, status, bytesTransferred); DbgPrint(\

return; }

/******************************************************************/ Resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file. // Used by WDFSample.rc //

// Next default values for new objects //

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif

/***************************************************8/ Sources

TARGETNAME=PCISample TARGETTYPE=DRIVER

KMDF_VERSION=1 INF_NAME=PCISample

MISCFILES=$(OBJ_PATH)\\$(O)\\$(INF_NAME).inf NTTARGETFILES=

C_DEFINES= $(C_DEFINES)

INCLUDES=$(INCLUDES);..\\..\\inc

SOURCES=driver.c \\ device.c \\ queue.c \\

WDFSample.rc

/*****************************************************************/ WDFSample.rc

//Microsoft Developer Studio generated resource script. //

#include \

#define APSTUDIO_READONLY_SYMBOLS

///////////////////////////////////////////////////////////////////////////// //

// Generated from the TEXTINCLUDE 2 resource. //

#define APSTUDIO_HIDDEN_SYMBOLS #include \

#undef APSTUDIO_HIDDEN_SYMBOLS #include \

///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS

///////////////////////////////////////////////////////////////////////////// // Chinese (P.R.C.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) #ifdef _WIN32

LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED #pragma code_page(936) #endif //_WIN32

#ifndef _MAC

///////////////////////////////////////////////////////////////////////////// //

// Version //

VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,0

PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else

FILEFLAGS 0x0L

#endif

FILEOS 0x40004L FILETYPE 0x3L FILESUBTYPE 0x7L BEGIN

BLOCK \ BEGIN

BLOCK \ BEGIN

VALUE \

VALUE \电子工业出版社\\0\ VALUE \ VALUE \ VALUE \

VALUE \最新WDF设备驱动程序开发(武安河)\\0\ VALUE \ VALUE \ VALUE \ VALUE \ VALUE \ VALUE \ END END

BLOCK \ BEGIN

VALUE \ END END

#endif // !_MAC

#ifdef APSTUDIO_INVOKED

///////////////////////////////////////////////////////////////////////////// //

// TEXTINCLUDE //

1 TEXTINCLUDE DISCARDABLE BEGIN

\END

2 TEXTINCLUDE DISCARDABLE

BEGIN

\ \

\ \ \END

3 TEXTINCLUDE DISCARDABLE BEGIN \ \END

#endif // APSTUDIO_INVOKED

#endif // Chinese (P.R.C.) resources

/////////////////////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED

///////////////////////////////////////////////////////////////////////////// //

// Generated from the TEXTINCLUDE 3 resource. //

///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED Exe

TestPciSample.cpp

// Test_PCISample.cpp : Defines the entry point for the console application.

//

#include \

#include #include #include #include #include #include

#include \

PCHAR

GetDevicePath(

IN LPGUID InterfaceGuid );

void doRead(void); void doWrite(void);

HANDLE hDevice = INVALID_HANDLE_VALUE;

int main(int argc, char* argv[]) { PCHAR DevicePath; printf(\

DevicePath = GetDevicePath((LPGUID)&PCISample_DEVINTERFACE_GUID);

hDevice = CreateFile(DevicePath,

GENERIC_READ|GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,

OPEN_EXISTING, 0,

NULL );

if (hDevice == INVALID_HANDLE_VALUE) { printf(\ return 0; } printf(\

doWrite(); doRead();

if (hDevice != INVALID_HANDLE_VALUE) { CloseHandle(hDevice); } return 0; }

PCHAR

GetDevicePath(

IN LPGUID InterfaceGuid ) {

HDEVINFO HardwareDeviceInfo;

SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;

PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL; ULONG Length, RequiredLength = 0; BOOL bResult;

HardwareDeviceInfo = SetupDiGetClassDevs( InterfaceGuid, NULL, NULL,

(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));

if (HardwareDeviceInfo == INVALID_HANDLE_VALUE) { printf(\ exit(1); }

DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0,

InterfaceGuid, 0,

&DeviceInterfaceData);

if (bResult == FALSE) {

printf(\

SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);

exit(1); }

SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, NULL, 0,

&RequiredLength, NULL );

DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LMEM_FIXED, RequiredLength);

if (DeviceInterfaceDetailData == NULL) {

SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); printf(\ exit(1); }

DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

Length = RequiredLength;

bResult = SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, Length,

&RequiredLength, NULL);

if (bResult == FALSE) {

printf(\

SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); LocalFree(DeviceInterfaceDetailData); exit(1); }

return DeviceInterfaceDetailData->DevicePath; }

void doRead(void) { char buf[32],*f; ULONG nRead; int i,j; // Read data from driver printf(\ ReadFile(hDevice, buf, 32, &nRead, NULL); printf(\ // Print what was read f=buf; for (i=0;i<2;i++) { for (j=0;j<16;j++) {

fprintf(stderr, \ };

fprintf(stderr, \ }; }

void doWrite(void) { char buf[32],*f; ULONG nWritten; int i,j; for (i=0; i<32; i++) { buf[i] = i; } // Write data to driver printf(\ WriteFile(hDevice, buf, 32, &nWritten, NULL); printf(\ // Print what was written f=buf; for (i=0;i<2;i++) { for (j=0;j<16;j++) {

fprintf(stderr, \ };

fprintf(stderr, \ }; }

/************************************************/ Public.h

#ifndef _USER_H #define _USER_H

#include

DEFINE_GUID(PCISample_DEVINTERFACE_GUID, \\ 0xd952c203, 0x56d4, 0x4289, 0x88, 0x92, 0xd4, 0x30, 0xf, 0x2a, 0x8, 0xd5);

#endif

Stdafx.h

// stdafx.h : include file for standard system include files,

// or project specific include files that are used frequently, but // are changed infrequently //

#if !defined(AFX_STDAFX_H__A588A4B8_5D40_4CC1_AC2D_48396E1F3473__INCLUDED_) #define AFX_STDAFX_H__A588A4B8_5D40_4CC1_AC2D_48396E1F3473__INCLUDED_

#if _MSC_VER > 1000 #pragma once

#endif // _MSC_VER > 1000

// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__A588A4B8_5D40_4CC1_AC2D_48396E1F3473__INCLUDED_)

Stdafx.cpp

// stdafx.cpp : source file that includes just the standard includes // Test_PCISample.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information

#include \

// TODO: reference any additional headers you need in STDAFX.H // and not in this file

本文来源:https://www.bwwdw.com/article/klkw.html

Top