C#,VirtualCopy的方式读写物理内存有问题,请指教

tiandi   2010-5-31 16:23 楼主

  1.     class WinCE_IO_Accessor
  2.     {
  3.         enum PageAccessFlags : uint
  4.         {
  5.             PAGE_NOACCESS = 0x01,
  6.             PAGE_READONLY = 0x02,
  7.             PAGE_READWRITE = 0x04,
  8.             PAGE_WRITECOPY = 0x08,
  9.             PAGE_EXECUTE = 0x10,
  10.             PAGE_EXECUTE_READ = 0x20,
  11.             PAGE_EXECUTE_READWRITE = 0x40,
  12.             PAGE_EXECUTE_WRITECOPY = 0x80,
  13.             PAGE_GUARD = 0x100,
  14.             PAGE_NOCACHE = 0x200,
  15.             PAGE_PHYSICAL = 0x400,
  16.             PAGE_WRITECOMBINE = 0x400
  17.         }

  18.         enum MemUsageFlags : uint
  19.         {
  20.             MEM_COMMIT = 0x1000,
  21.             MEM_RESERVE = 0x2000,
  22.             MEM_DECOMMIT = 0x4000,
  23.             MEM_RELEASE = 0x8000,
  24.             MEM_FREE = 0x10000,
  25.             MEM_PRIVATE = 0x20000,
  26.             MEM_MAPPED = 0x40000,
  27.             MEM_RESET = 0x80000,
  28.             MEM_TOP_DOWN = 0x100000,
  29.             MEM_AUTO_COMMIT = 0x200000,
  30.             MEM_4MB_PAGES = 0x80000000
  31.         }

  32.         [DllImport("Coredll.dll", EntryPoint = "VirtualAlloc", SetLastError = true)]
  33.         private static extern IntPtr VirtualAlloc(
  34.             IntPtr lpAddress,
  35.             uint dwSize,
  36.             MemUsageFlags flAllocationType,
  37.             PageAccessFlags flProtect);

  38.         [DllImport("Coredll.dll", EntryPoint = "VirtualCopy", SetLastError = true)]
  39.         private static extern bool VirtualCopy(
  40.             IntPtr lpvDest,
  41.             IntPtr lpvSrc,
  42.             uint cbSize,
  43.             PageAccessFlags fdwProtect);

  44.         [DllImport("Coredll.dll", EntryPoint = "VirtualFree", SetLastError = true)]
  45.         private static extern bool VirtualFree(
  46.             IntPtr lpAddress,
  47.             uint cbSize,
  48.             MemUsageFlags dwFreeType);

  49.         const uint DRIVER_GLOBALS_PHYSICAL_MEMORY_START = 0xac059000;
  50.         const uint BASE_ADDR = DRIVER_GLOBALS_PHYSICAL_MEMORY_START / 256;
  51.         const uint SIZE = 8;
  52.         public IntPtr buf;

  53.         public WinCE_IO_Accessor()
  54.         {
  55.             buf = VirtualAlloc(IntPtr.Zero, SIZE, MemUsageFlags.MEM_RESERVE, PageAccessFlags.PAGE_NOACCESS);

  56.             if (buf == IntPtr.Zero)
  57.             {
  58.                 throw new Exception("VirtualAlloc Fail");
  59.             }

  60.             if (!VirtualCopy(buf, (IntPtr)BASE_ADDR, SIZE, PageAccessFlags.PAGE_READWRITE |
  61.                 PageAccessFlags.PAGE_NOCACHE | PageAccessFlags.PAGE_PHYSICAL))
  62.             {
  63.                 throw new Exception("VirtualCopy Fail");
  64.             }

  65.             byte a = 1;
  66.             Marshal.WriteByte(buf, a);
  67.             byte b = Marshal.ReadByte(buf); //这里读出的b=0

  68.             VirtualFree(buf, 0, MemUsageFlags.MEM_RELEASE);
  69.         }
  70.     }



帮别人做一个WinCE5.0下的小软件,要和硬件IO端口打交道,所以需要读写物理内存
C++很不熟悉,所以决定用C#,效率高点
读写物理内存的代码如上,写入一个字节1后,再读出来是0
现在硬件还没到位,在VS2008自带的模拟器(PPC2003)里跑的

不知道哪里出问题了,请明白人指点
非常感谢

回复评论 (15)

自己坐沙发是一种悲哀~
点赞  2010-5-31 21:00
没人关注么,就算不确定给点思路也行啊,大家一起讨论一下
点赞  2010-6-1 10:47
设计硬件的最好还是接上硬件调试,个人认为电脑很难仿
点赞  2010-6-1 11:33
引用: 引用 3 楼 suntion 的回复:

设计硬件的最好还是接上硬件调试,个人认为电脑很难仿

有道理,不过硬件还得段时间到位,想在这之前把路走通
我感觉在模拟器上跑不通的话在硬件上也够呛
没有这方面的经验,不知道是不是这样的
点赞  2010-6-1 14:03
大侠们,来挽救我一下吧
点赞  2010-6-1 19:22
你直接往里面写8个,然后直接打印出来看一下。
点赞  2010-6-1 22:16
UINT nNewSize = (UINT)(2048*2048*200); // 1024.0) * 1024;
double * pNewBuffer =(double*)  VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);
if (pNewBuffer)
{
  //测试虚拟内存。
double Block;
for(int i =0;i<100;i++)
  {
  
  Block=10.11*i;
  memcpy(&pNewBuffer,&Block,sizeof(Block));

  }
double tt;
tt=(pNewBuffer[99]);
CString s;
s.Format(_T("The total is %f"),tt);
AfxMessageBox(s) ;
//删除分配的内存。
VirtualFree(pNewBuffer,0,MEM_RELEASE);

}


文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/c++/cppsl/2008521/117523.html
点赞  2010-6-1 22:30
引用: 引用 7 楼 macrozhang001 的回复:

UINT nNewSize = (UINT)(2048*2048*200); // 1024.0) * 1024;
double * pNewBuffer =(double*)  VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);
if (pNewBuffer)
{
  //测试虚拟内存。
double Block;
……

这个例子和我要做的事情不一样,我要做的是直接操作物理内存,所以用VirtualCopy
如果直接开一块虚拟内存来读写,是可以成功的,如下

  1.             buf = VirtualAlloc(IntPtr.Zero, SIZE, MemUsageFlags.MEM_COMMIT, PageAccessFlags.PAGE_READWRITE);

  2.             if (buf == IntPtr.Zero)
  3.             {
  4.                 throw new Exception("VirtualAlloc Fail");
  5.             }

  6.             byte a = 1;
  7.             Marshal.WriteByte(buf, a);
  8.             byte b = Marshal.ReadByte(buf); //这里读出的b=1

  9.             VirtualFree(buf, 0, MemUsageFlags.MEM_RELEASE);
点赞  2010-6-2 08:42
每天自己顶,期待帮助
点赞  2010-6-2 11:26
为啥没人来指点一下呢。。。
点赞  2010-6-2 16:21
顶一下,
点赞  2010-6-6 22:23
带着个标志PAGE_PHYSICAL的话
貌似你的BASEADDR需要做移位操作,好像是左移8位吧,具体你看看msdn。
点赞  2010-6-7 20:38
引用: 引用 12 楼 rushonin 的回复:

带着个标志PAGE_PHYSICAL的话
貌似你的BASEADDR需要做移位操作,好像是左移8位吧,具体你看看msdn。

const uint BASE_ADDR = DRIVER_GLOBALS_PHYSICAL_MEMORY_START / 256;
除了256,已经移过了
点赞  2010-6-8 23:14
我拿到实际硬件了
调用板子厂家提供的API搞定
现在回想一下, 觉得应该是在模拟器里写的这块地址有问题,不允许写,所以写不进去
谢谢大家的关注和解答,结贴了
点赞  2010-6-8 23:21
PVOID MmMapIoSpace(
  PHYSICAL_ADDRESS PhysicalAddress,
  ULONG NumberOfBytes,
  BOOLEAN CacheEnable
);
点赞  2010-6-8 23:48
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复