IWDFDevice3::MapIoSpace 方法 (wudfddi.h)
[警告: UMDF 2 是最新版本的 UMDF,取代了 UMDF 1。 所有新的 UMDF 驱动程序都应使用 UMDF 2 编写。 未向 UMDF 1 添加新功能,并且较新版本的 Windows 10 上对 UMDF 1 的支持有限。 通用 Windows 驱动程序必须使用 UMDF 2。 有关详细信息,请参阅使用 UMDF 入门。]
MapIoSpace 方法将给定的物理地址范围映射到系统地址空间,并返回伪基址。
语法
HRESULT MapIoSpace(
[in] PHYSICAL_ADDRESS PhysicalAddress,
[in] SIZE_T NumberOfBytes,
[in] MEMORY_CACHING_TYPE CacheType,
[out] void **pPseudoBaseAddress
);
参数
[in] PhysicalAddress
指定要映射的 I/O 范围的起始 64 位物理地址。
[in] NumberOfBytes
指定大于零的值,指示要映射的字节数。
[in] CacheType
指定 MEMORY_CACHING_TYPE 值,该值指示用于映射物理地址范围的缓存属性。 MEMORY_CACHING_TYPE枚举类型在 Wudfwdm.h 中定义。
[out] pPseudoBaseAddress
接收指向伪基址的指针的位置的地址。
返回值
如果操作成功,该方法将返回S_OK。 否则,此方法返回 Winerror.h 中定义的错误代码之一。
注解
如果驱动程序在CM_PARTIAL_RESOURCE_DESCRIPTOR结构中收到 CmResourceTypeMemory 类型的已翻译资源,则必须在设备启动期间调用此方法。 MapIoSpace 将资源列表中返回的物理地址映射到称为伪基址的框架托管地址。
然后,驱动程序可以使用伪基址访问具有 READ_REGISTER_Xxx 和 WRITE_REGISTER_Xxx 函数的设备寄存器。 有关示例,请参阅 在 UMDF 1.x 驱动程序中读取和写入设备寄存器。
调用 MapIoSpace 的驱动程序必须将 UmdfDirectHardwareAccess INF 指令设置为 AllowDirectHardwareAccess。
如果驱动程序将 UmdfRegisterAccessMode INF 指令设置为 RegisterAccessUsingUserModeMapping,则调用 MapIoSpace 还会将给定的物理地址范围映射到驱动程序随后可以通过调用 GetHardwareRegisterMappedAddress 访问的用户模式基地址范围。
有关 UMDF 驱动程序可以使用的 INF 指令的详细信息,请参阅 在 INF 文件中指定 WDF 指令。
PHYSICAL_ADDRESS类型在 Wudfwdm.h 中定义,如下所示:
typedef LARGE_INTEGER PHYSICAL_ADDRESS;
示例
在以下代码示例中,UMDF 驱动程序使用其 IPnpCallbackHardware2::OnPrepareHardware 回调函数检查其内存映射的寄存器资源,并将其映射到用户模式地址空间中。 然后,该示例实现访问内存位置的 WriteToDevice 方法。 然后,驱动程序从其 IPnpCallbackHardware2::OnReleaseHardware 回调调用 UnmapIoSpace。 驱动程序的 INF 文件必须通过将 UmdfDirectHardwareAccess 指令设置为 AllowDirectHardwareAccess 来启用 UMDF 硬件访问功能。
HRESULT
CMyDevice::OnPrepareHardware(
__in IWDFDevice3 * pWdfDevice,
__in IWDFCmResourceList * pRaw,
__in IWDFCmResourceList * pTrans
)
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR desc = NULL;
PHYSICAL_ADDRESS regBasePA = {0};
ULONG regLength = 0;
BOOLEAN found = FALSE;
HRESULT hr = S_OK;
//
// Scan the list to identify our resource.
//
for (i=0; i < pWdfResTranslated->GetCount(); i++) {
desc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) pTrans->GetDescriptor(i);
switch (desc->Type) {
case CmResourceTypeMemory:
//
// See if this is the memory resource we’re looking for.
//
if (desc->u.Memory.Length == 0x200) {
regsBasePA = desc->u.Memory.Start;
regsLength = desc->u.Memory.Length;
found = TRUE;
}
break;
default:
// Ignore all other descriptors.
break;
}
}
//
// Map the resource. Store the register base in partner device
// object for later access.
//
if (found) {
hr = pWdfDevice->MapIoSpace(regBasePA,
regLengthlength,
MmNonCached,
(void **)&m_RegBase);
if (SUCCEEDED(hr)) {
//
// Store the register range in partner object. This will
// be needed for unmapping.
//
m_RegLength = regLength;
}
}
…
}
//
// UMDF driver uses one of the register access APIs such as
// WRITE_REGISTER_Xxx or READ_REGISTER_Xxx macros to access device register.
//
VOID
CMyQueue::WriteToDevice(
__in IWDFDevice3* pWdfDevice,
__in UCHAR Value
)
{
//
// Write the UCHAR value at offset 2 from register base.
//
WRITE_REGISTER_UCHAR(pWdfDevice,
(m_MyDevice->m_RegBase)+2,
Value);
}
HRESULT
CMyDevice::OnReleaseHardware(
__in IWDFDevice3 * pWdfDevice,
__in IWDFCmResourceList * pTrans
)
{
//
// Unmap registers memory resource.
//
pWdfDevice->UnmapIoSpace(m_RegBase, m_RegLength);
return S_OK;
}
要求
要求 | 值 |
---|---|
结束支持 | 在 UMDF 2.0 及更高版本中不可用。 |
目标平台 | 桌面 |
最低 UMDF 版本 | 1.11 |
标头 | wudfddi.h |
DLL | WUDFx.dll |