资源描述:
《wince内存直接读写》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、2.对物理内存的直接读写 在PC环境下,Windows是不允许用户态进程直接访问内存的,任何对内存的访问都会引起程序的异常。而在嵌入式设备中,需要直接对内存进行读写,以此来提高处理速度,此外,在ARM体系中,I/O被映射到高端的地址进行访问,只有读写物理地址,I/O的驱动才能高效地运行。WindowsCE中有一些API提供了对物理内存的“直接”访问。不过,在访问之前,必须把物理内存映射到虚拟地址中,通过虚拟地址才能读写物理内存。 PHYSICAL_ADDRESS描述了WindowsCE的物理内存结构体,WindowsCE在ceddk.h中定义了PHY
2、SICAL_ADDRESS,其定义如下: n 在ceddk.h中typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; n 在winnt.h中typedef union _LARGE_INTEGER{ struct{DWORD LowPart; LONG HighPart; }; LONGLONG QuadPart;}LARGE_INTEGER; 可见,WindowsCE中用64位来代表物理地址,对于大多数32位的CPU而言,只需要把它的HighPart设置为0就可以了
3、。 VirtualAlloc()函数是WindowsCE中分配连续虚拟地址的API,VirtualCopy()函数将一段物理内存映射到虚拟地址。因此,在进程中访问物理地址,就像访问虚拟地址一样方便,当然,如何选择虚拟地址是需要研究的。// 申请虚拟内存LPVOID VirtualAlloc( LPVOID lpAddress, // 希望的虚拟内存起始地址 DWORD dwSize, // 以字节为单位的大小 DWORD flAllocationType, // 申请类型,分为Reserve和Commit
4、DWORD flProtect // 访问权限);// 把物理内存绑定到虚拟地址空间BOOL VirtualCopy( LPVOID lpvDest, // 虚拟内存的目标地址 LPVOID lpvSrc, // 物理内存地址 DWORD cbSize, // 要绑定的大小 DWORD fdwProtect // 访问权限);VirtualAlloc对虚拟内存的申请分为两步,保留MEM_RESERVE和提交MEM_COMMIT。其中MEM_RESERV
5、E只是在进程的虚拟地址空间内保留一段,并不分配实际的物理内存,因此保留的虚拟内存并不能被应用程序直接使用。MEM_COMMIT阶段才真正为虚拟内存分配物理内存。 下面的代码显示了如何使用VirtualAlloc和VirtualCopy来访问物理内存。因为VirtualCopy负责把一段物理内存和虚拟内存绑定,所以VirtualAlloc执行时只需要对内存保留,没有必要提交。FpDriverGlobals = (PDRIVER_GLOBALS) VirtualAlloc( 0, DRIVER_GLOBALS_PHYSICAL_MEMORY
6、_SIZE, MEM_RESERVE, PAGE_NOACCESS); if (FpDriverGlobals == NULL) { ERRORMSG(DRIVER_ERROR_MSG, (TEXT(" VirtualAlloc failed!r"))); return; } else { if (!VirtualCopy( (PVOID)FpDriverGlobals, (PVOID)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START), DRIVER_GLOBALS
7、_PHYSICAL_MEMORY_SIZE, (PAGE_READWRITE
8、 PAGE_NOCACHE))) { ERRORMSG(DRIVER_ERROR_MSG, (TEXT("VirtualCopy failed!r"))); return; } } CEDDK还提供了函数MmMapIoSpace,用来把一段物理内存直接映射到虚拟内存。用MmMapIoSpace申请的内存要用MmUnmapIoSpace释放,此函数的原型如下:PVOID MmMapIoSpace( PHYSICAL_ADDRES
9、S PhysicalAddress, // 起始物理地址 ULONG N