【发布时间】:2014-06-20 14:20:22
【问题描述】:
我需要在运行 Windows Embedded Compact 2013 的平台上以用户模式访问物理内存。我找到了一篇文章。内存映射在内核模式驱动程序中完成,并将地址返回给用户模式程序。
在内核驱动中
BOOL BTN_IOControl(DWORD context, DWORD code, UCHAR *pInBuffer, DWORD inSize, UCHAR *pOutBuffer,DWORD outSize, DWORD *pOutSize)
{
PDWORD tValue = (PDWORD)pOutBuffer;
switch(code)
{
case IOCTL_MAP_MEMORY:
*tValue = GetVirtualAddress();
*pOutSize = 4;
break;
.....
}
GetVirtualMemory函数如下
LPOID GetVirtualAddress()
{
volatile DWORD sDevPhysAddr = 0xe000a000;
volatile DWORD dwSize = PAGE_SIZE;
LPVOID lpUserAddr;
volatile ULONG SourceSize;
volatile ULONG SourcePhys;
void* pvProcess = (void*)GetCallerVMProcessId();
SourcePhys = sDevPhysAddr & ~(PAGE_SIZE - 1);
SourceSize = PAGE_SIZE;
RETAILMSG(1, (L"Address: %08x Size: %08x.\r\n", SourcePhys, SourceSize));
lpUserAddr = (LPDWORD)VirtualAllocEx(pvProcess, 0, SourceSize, MEM_RESERVE, PAGE_NOACCESS);
if (lpUserAddr == NULL) {
RETAILMSG(1, (L"VirtualAllocEx failed. GetLastError %d.\r\n", GetLastError()));
return NULL;
}
if (!VirtualCopyEx(pvProcess, lpUserAddr, GetCurrentProcess(), (PVOID)
/*(*/SourcePhys/* >> 8)*/, SourceSize,
/*PAGE_PHYSICAL | */PAGE_READWRITE | PAGE_NOCACHE)) {
RETAILMSG(1, (L"VirtualCopyEx failed. Error %d.\r\n", GetLastError()));
return NULL;
}
RETAILMSG(1, (L"Before round up lpUserAddr=0x%x\r\n", lpUserAddr));
lpUserAddr = (LPVOID)((ULONG)lpUserAddr + (sDevPhysAddr & (PAGE_SIZE - 1)));
shared_mem = lpUserAddr;
RETAILMSG(1, (L"After round up gUserAddr=0x%x\r\n", shared_mem));
return lpUserAddr;
}
代码是映射物理内存0xe000a000(zynq芯片中的GPIO基地址)。代码在 VirtualCopyEx 中失败,并出现错误 87(无效参数)。但是该代码使用 0x81F00000 处的基本物理地址(该地址由原始程序员使用)。我的问题是如何启用 GPIO 地址的映射。我也愿意尝试任何其他可能的方法。
【问题讨论】:
标签: memory-management arm windows-ce xilinx