




已阅读5页,还剩22页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Dirs.DIRS= sysSys:/*-*/Device.c#include private.h#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)#endifNTSTATUSPCISample_EvtDeviceAdd( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit ) NTSTATUSstatus; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES deviceAttributes; WDFDEVICEdevice; PDEVICE_CONTEXTpDeviceContext; WDF_INTERRUPT_CONFIGinterruptConfig; WDF_IO_QUEUE_CONFIGioQueueConfig; 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;NTSTATUSInitializeDMA( IN WDFDEVICE Device ) NTSTATUSstatus; PDEVICE_CONTEXTpDeviceContext;WDF_DMA_ENABLER_CONFIGdmaConfig; 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(WdfDmaEnablerCreate failed: %!STATUS!n, status);return status;/ Create a new DmaTransaction./创建一个DMA传输status = WdfDmaTransactionCreate( pDeviceContext-DmaEnabler, WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext-DmaTransaction );if(!NT_SUCCESS(status) DbgPrint(WdfDmaTransactionCreate failed: %!STATUS!n, status); return status;NTSTATUSPCISample_EvtDevicePrepareHardware( IN WDFDEVICE Device, IN WDFCMRESLIST ResourceList, IN WDFCMRESLIST ResourceListTranslated ) PDEVICE_CONTEXT pDeviceContext;ULONGi;PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor; PAGED_CODE(); DbgPrint(EvtDevicePrepareHardware - beginsn); pDeviceContext = GetDeviceContext(Device);pDeviceContext-MemBaseAddress = NULL; / / Parse the resource list and save the resource information. / for (i=0; i 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(EvtDevicePrepareHardware - endsn); return STATUS_SUCCESS;NTSTATUSPCISample_EvtDeviceReleaseHardware( IN WDFDEVICE Device, IN WDFCMRESLIST ResourceListTranslated ) PDEVICE_CONTEXTpDeviceContext; PAGED_CODE(); DbgPrint(EvtDeviceReleaseHardware - beginsn); pDeviceContext = GetDeviceContext(Device);if(pDeviceContext-MemBaseAddress) /MmUnmapIoSpace解除物理地址与系统内核模式地址的关联MmUnmapIoSpace(pDeviceContext-MemBaseAddress, pDeviceContext-MemLength);pDeviceContext-MemBaseAddress = NULL;DbgPrint(EvtDeviceReleaseHardware - endsn);return STATUS_SUCCESS;/*-*/driver.c#include private.h#ifdef ALLOC_PRAGMA#pragma alloc_text(INIT, DriverEntry)#endifNTSTATUSDriverEntry( 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 devcon install PCISample.inf rootPCISample to install;-*/VersionSignature=$WINDOWS NT$Class=WDFBOOKClassGuid=EF1941A7-645B-4668-B05B-287D30169435Provider=%ProviderName%DriverVer=12/28/2008,6.0.6000.16386; = Class section =ClassInstall32Addreg=SampleClassReg SampleClassRegHKR,0,%DeviceClassName%HKR,Icon,-18;*; PCISample Install Section;*Manufacturer%MfgName%=Standard,NTx86; Following section is meant for Windows 2000 as it ; cannot parse decorated model sectionsStandard; Hw Id is rootPCISample;%PCISample.DeviceDesc%=PCISample_Device, PCIVEN_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, PCIVEN_5858&DEV_0002&SUBSYS_00000000&REV_01DestinationDirsPCISample_Files_Driver = 12PCISample_Device.NTCopyFiles=PCISample_Files_DriverPCISample_Files_DriverPCISample.sys;- Service installationPCISample_Device.NT.ServicesAddService = PCISample,0x00000002, PCISample_AddService; - PCISample driver install sectionsPCISample_AddServiceDisplayName = %PCISample.SVCDESC%ServiceType = 1 ; SERVICE_KERNEL_DRIVERStartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMALServiceBinary = %12%PCISample.sys;- WDF Coinstaller installation -;DestinationDirsCoInstaller_CopyFiles = 11PCISample_Device.NT.CoInstallersCopyFiles=CoInstaller_CopyFilesAddReg=CoInstaller_AddRegCoInstaller_CopyFileswdfcoinstaller01007.dllCoInstaller_AddRegHKR,CoInstallers32,0x00010000, wdfcoinstaller01007.dll,WdfCoInstallerPCISample_Device.NT.WdfKmdfService = PCISample, PCISample_wdfsectPCISample_wdfsectKmdfLibraryVersion = 1.7StringsProviderName=Windows最新WDF设备驱动程序开发MfgName=武安河DeviceClassName=WDF范例PCISample.DeviceDesc = PCISamplePCISample.SVCDESC = WDF PCISample Service/*/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 public.h#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 0x1000typedef struct _DEVICE_CONTEXT WDFINTERRUPTInterrupt; WDFDMAENABLERDmaEnabler; WDFDMATRANSACTIONDmaTransaction;PVOIDMemBaseAddress;ULONGMemLength; DEVICE_CONTEXT, *PDEVICE_CONTEXT;WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)NTSTATUSDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );NTSTATUSPCISample_EvtDeviceAdd( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit );NTSTATUSInitializeDMA( IN WDFDEVICE Device );NTSTATUSPCISample_EvtDevicePrepareHardware( IN WDFDEVICEDevice, IN WDFCMRESLIST ResourceList, IN WDFCMRESLIST ResourceListTranslated );NTSTATUSPCISample_EvtDeviceReleaseHardware( IN WDFDEVICEDevice, IN WDFCMRESLIST ResourceListTranslated );VOIDPCISample_EvtIoWrite( IN WDFQUEUEQueue, IN WDFREQUESTRequest, IN size_tLength );VOIDPCISample_EvtIoRead( IN WDFQUEUEQueue, IN WDFREQUESTRequest, IN size_tLength );BOOLEANPCISample_EvtProgramDma( IN WDFDMATRANSACTION Transaction, IN WDFDEVICE Device, IN WDFCONTEXT Context, IN WDF_DMA_DIRECTION Direction, IN PSCATTER_GATHER_LIST SgList );BOOLEANPCISample_EvtInterruptIsr( IN WDFINTERRUPT Interrupt, IN ULONG MessageID );VOIDPCISample_EvtInterruptDpc( IN WDFINTERRUPT Interrupt, IN WDFOBJECT Device );#endif/*/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/*/Queue.c #include private.h/编程思路:一写一读,PCI将数据写入CY7C09449的RAM后,再通过DMA将数据读回来VOIDPCISample_EvtIoWrite( IN WDFQUEUEQueue, IN WDFREQUESTRequest, IN size_tLength ) NTSTATUSstatus; WDFMEMORYmemory; WDFDEVICEdevice; PDEVICE_CONTEXT pDeviceContext;PUCHARpRAM; ULONGlength; / Get the memory buffer status = WdfRequestRetrieveInputMemory(Request, &memory); if( !NT_SUCCESS(status) ) WdfRequestComplete(Request, status); return; device = WdfIoQueueGetDevice(Queue); pDeviceContext = GetDeviceContext(device);pRAM = pDeviceContext-MemBaseAddress;pRAM+= RAM;length = Length; if (length MAXNLEN) length = MAXNLEN; /将应用程序的数据拷贝到CY7C09449的RAM中 status = WdfMemoryCopyToBuffer(memory, 0, pRAM, length); WdfRequestCompleteWithInformation(Request, status, length); return;VOIDPCISample_EvtIoRead( IN WDFQUEUEQueue, IN WDFREQUESTRequest, IN size_tLength )NTSTATUS status;PDEVICE_CONTEXT pDeviceContext;WDFDMATRANSACTION dmaTransaction; pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue);dmaTransaction = pDeviceContext-DmaTransaction;do / / Initialize this new DmaTransaction. /采用Request输出缓存区作为DMA读缓存区status = WdfDmaTransactionInitializeUsingRequest(dmaTransaction,Request,PCISample_EvtProgramDma,WdfDmaDirectionReadFromDevice);if(!NT_SUCCESS(status) DbgPrint(WdfDmaTransactionInitializeUsingRequest failed: %!STATUS!n, status);break; / / Execute this DmaTransaction. /status = WdfDmaTransactionExecute(dmaTransaction, WDF_NO_CONTEXT);if(!NT_SUCCESS(status) DbgPrint(WdfDmaTransactionExecute failed: %!STATUS!n, status);break;status = STATUS_SUCCESS; while(0);if(!NT_SUCCESS(status) WdfDmaTransactionRelease(dmaTransaction);WdfRequestComplete(Request, status); return;/-/-BOOLEANPCISample_EvtProgramDma( IN WDFDMATRANSACTION Transaction, IN WDFDEVICE Device, IN WDFCONTEXT Context, IN WDF_DMA_DIRECTION Direction, IN PSCATTER_GATHER_LIST SgList )/*+ The framework calls a drivers EvtProgramDma event callback function when the driver calls WdfDmaTransactionExecute and the system has enough map registers to do the transfer. The callback function must program the hardware to start the transfer. A single transaction initiated by calling WdfDmaTransactionExecute may result in multiple calls to this function if the buffer is too large and there arent enough map registers to do the whole transfer.-*/ NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; ULONGaddress; ULONGlength;PUCHARpREG; pDeviceContext = GetDeviceContext(Device);pREG = pDeviceContext-MemBaseAddress; ASSERT(SgList-NumberOfElements = 1); ASSERT(SgList-Elements0.Address.HighPart = 0); / / Only the first Scatter/Gather element is relevant for packet mode. / CY09449 only does 32-bit DMA transfer operations: only low part of / physical address is usable. / address = SgList-Elements0.Address.LowPart; length = SgList-Elements0.Length; if (length MAXNLEN) length = MAXNLEN; / Acquire this devices InterruptSpinLock.WdfInterruptAcquireLock( pDeviceContext-Interrupt );/允许H:DMA中断WRITE_REGISTER_ULONG(PULONG)(pREG+HINT),0x2003FF);/下面几条语句设置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 spinlockWdfInterruptReleaseLock( pDeviceContext-Interrupt ); return TRUE;BOOLEANPCISample_EvtInterruptIsr( IN WDFINTERRUPT Interrupt, IN ULONG MessageID ) PDEVICE_CONTEXT pDeviceContext;PUCHARpREG;USHORTstatus;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;elsereturn FALSE;/ 不是由该设备产生的中断,返回FALSEVOIDPCISample_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 = pDev
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑施工劳务分包协议条款详解
- 采购成本估算及谈判支持工具
- 2025-2030儿童早教行业市场现状分析与未来发展趋势及投资价值评估报告
- 2025-2030儿童传统文化教育市场发展分析与商业模式及投资前景预测报告
- 公司车辆借用协议模板下载
- 多语言多行业翻译工作手册
- 我的成长之路写人类的议论文话题14篇
- 英语五年级上册Myfamily单元词汇学习教案
- 农村净水合同(标准版)
- 娱乐活动组织及执行服务合同
- 输液空气的栓塞及预防
- 清洁生产简述与实例分析课件
- 大学食品安全主题教育
- 入院患者接待暂空床讲解
- 常用护理质量管理工具
- 中学物理实验室安全管理制度
- 沂沭泗河洪水东调南下续建工程南四湖湖东堤工程施工组织设计
- 制鞋工艺流程
- 土石方工程运输合同
- 国际伤口治疗师汇报
- 《电工基础(第2版)》中职全套教学课件
评论
0/150
提交评论