Windows驱动资源的使用一
来源:互联网 发布:传统武术知乎 编辑:程序博客网 时间:2024/05/22 21:04
上次讲到了,Windows驱动中的资源,今天着重讲一下,Windows资源,如何使用。关于中断,内存,IO这些,以后再讲。今天重点讲一下,总线驱动的引用。我们知道,在设备驱动中,经常会使用I2C,GPIO这些资源,但是我们如何进行操作了,当然,我们可以直接进行IO映射。直接I2C,GPIO地址进行操作,但是这种方式不安全,且MSFT不推荐。所以,MSFT在后来的CM_PARTIAL_RESOURCE_DESCRIPTOR结构体中,加上了如下结构体:
95. struct {
96. UCHAR Class;
97. UCHAR Type;
98. UCHAR Reserved1;
99. UCHAR Reserved2;
100. ULONG IdLowPart;
101. ULONG IdHighPart;
102. } Connection;
我们通过这个结构体,可以得到一个对我们配置资源总线的一个引用。即通过这个域,我们可以把它组成了一ID,通过这个ID,就可以和我们设备驱动底层的GPIO,I2C这些驱动进行通讯。
下面贴出MSDN中的一个实例。
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; ...}
我们得到这个描述符。就可以进行和目标IO进行通讯了,继续看:
NTSTATUS IoRoutine(WDFDEVICE Device) { XYZ_DEVICE_CONTEXT *DeviceExtension; UNICODE_STRING ReadString; WCHAR ReadStringBuffer[100]; WDF_OBJECT_ATTRIBUTES ObjectAttributes; WDF_IO_TARGET_OPEN_PARAMS OpenParams; WDFIOTARGET IoTarget; BOOL DesiredAccess; NTSTATUS Status; 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 = FILE_GENERIC_READ; } else { DesiredAccess = FILE_GENERIC_WRITE; } WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(&OpenParams, ReadString, DesiredAccess); Status = WdfIoTargetOpen(IoTarget, &OpenParams); if (!NT_SUCCESS(Status)) { goto IoErrorEnd; } ...
再看实际的GPIO读写状态:
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); } ...
我们再来看下Connection的MSDN的说明:
先看Class:
CM_RESOURCE_CONNECTION_CLASS_GPIO或者CM_RESOURCE_CONNECTION_CLASS_SERIAL
再看Type:
CM_RESOURCE_CONNECTION_TYPE_GPIO_IO或者CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C,CM_RESOURCE_CONNECTION_TYPE_SERIAL_SPI,CM_RESOURCE_CONNECTION_TYPE_SERIAL_UART
IdLowPart:64位连接ID的低32位。
IdHighPart:64位连接ID的高32位。
我们可以举一反三,在I2C, SPI中都可以这样用,当然,有使用,MSFT为我们封装了后序的IOCTL的操作,比如,直接提供I2CReadRegister,或者I2CWriteRegister.
- Windows驱动资源的使用一
- Windows驱动中的资源
- 驱动中使用资源
- Windows 驱动开发资源链接
- Windows驱动开发的一些资源下载记录
- Windows驱动开发的一些资源下载记录
- Windows资源(一)菜单
- windows phone:资源(一)
- windows驱动开发 一
- [Windows 监控]使用windows自带的工具去对某一进程实现监控,并取得这一进程对系统的资源使用情况
- Windows虚拟内存的使用(一)
- Windows驱动开发遇到的问题(一)
- Windows驱动开发(10) - 驱动程序的同步处理(一)
- Windows 驱动开发笔记(一)
- Windows驱动开发(一)
- Windows 驱动入门(一)
- Android中资源文件的使用(一):如何使用资源
- 详细解析windows usb驱动和linux usb驱动的相似和差异(一)
- 指导目标
- 2012.9.15
- 谈谈对金山手机毒霸事件的看法
- fl2440LED驱动程序总结
- IOS 常见错误 ---更新中
- Windows驱动资源的使用一
- 【转】PNG图像文件存储结构(1)
- WinForm Enter键Esc键的封装处理
- iPhone5首位采用ARM Cortex A15
- cocos2d-x学习笔记——小心文件大小写
- VB 6.0 与SQL Sever2000
- SQL Server游标的使用
- 搜索链表一次
- 第八章 标准IO库