Метод IWDFDevice3::MapIoSpace (wudfddi.h)
[ предупреждение: UMDF 2 является последней версией UMDF и заменяет UMDF 1. Все новые драйверы UMDF должны быть написаны с помощью UMDF 2. Новые функции не добавляются в UMDF 1, а поддержка UMDF 1 в более новых версиях Windows 10 ограничена. Универсальные драйверы 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
Указывает начальный 64-разрядный физический адрес диапазона ввода-вывода для сопоставления.
[in] NumberOfBytes
Указывает значение, больше нуля, указывающее число байтов, которое необходимо сопоставить.
[in] CacheType
Задает значение MEMORY_CACHING_TYPE, указывающее атрибут кэша, используемый для сопоставления диапазона физических адресов. Тип перечисления MEMORY_CACHING_TYPE определен в Wudfwdm.h.
[out] pPseudoBaseAddress
Адрес расположения, получающего указатель на псевдо базовый адрес.
Возвращаемое значение
Метод возвращает S_OK, если операция выполнена успешно. В противном случае этот метод возвращает один из кодов ошибок, определенных в Winerror.h.
Замечания
Драйвер должен вызывать этот метод во время запуска устройства, если он получает переведенные ресурсы типа CmResourceTypeMemory в структуре CM_PARTIAL_RESOURCE_DESCRIPTOR. MapIoSpace сопоставляет физический адрес, возвращенный в списке ресурсов, с управляемым платформой адресом, который называется псевдо базовым адресом.
Затем драйвер может использовать псевдо базовый адрес для доступа к регистрам устройств с помощью функций READ_REGISTER_Xxx и WRITE_REGISTER_Xxx. Пример см. в статье чтение и запись в регистры устройств в драйверах UMDF 1.x.
Драйвер, вызывающий MapIoSpace, должен задать директиву INF UmdfDirectHardwareAccess INF для AllowDirectHardwareAccess.
Если драйвер задает директиву INF UmdfRegisterAccessModeRegisterAccessUsingUserModeMapping, вызов MapIoSpace также сопоставляет заданный диапазон физических адресов с базовым диапазоном адресов в режиме пользователя, к которому драйвер может получить доступ, вызвав GetHardwareRegisterMappedAddress.
Дополнительные сведения о директивах INF, которые могут использовать драйверы UMDF, см. в разделе Указание директив WDF в INF-файлах.
Тип PHYSICAL_ADDRESS определен в Wudfwdm.h следующим образом:
typedef LARGE_INTEGER PHYSICAL_ADDRESS;
Примеры
В следующем примере кода драйвер UMDF использует свою IPnpCallbackHardware2::OnPrepareHardware функцию обратного вызова для проверки ресурсов, сопоставленных с памятью, и сопоставляет их с адресным пространством в режиме пользователя. Затем в примере реализуется метод WriteToDevice, который обращается к расположениям памяти. Затем драйвер вызывает UnmapIoSpace из IPnpCallbackHardware2::OnReleaseHardware обратного вызова. INF-файл драйвера должен включить функцию доступа к оборудованию UMDF, задав директиву UmdfDirectHardwareAccess значение AllowDirectHardwareAccess.
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 |