How To Configure Windows CE for Use With DMA Devices (299355)



The information in this article applies to:

  • Microsoft Windows CE Platform Builder 2.12
  • Microsoft Windows CE Platform Builder 3.0

This article was previously published under Q299355

SUMMARY

This article provides procedures for users of Platform Builder who want to communicate with a device through direct memory access (DMA). The topics covered include RESERVED keyword and contiguous memory, use of VirtualAlloc and VirtualCopy to map the reserved address range into a process space, direct access by Interrupt service routines (ISR), and lack of a MapVirtualToPhysical API.

MORE INFORMATION

The Windows CE Operating System (OS) does not directly support DMA. There are no scatter/gather routines in the OS to support DMA transfer. However, users of Platform Builder who want to communicate with DMA devices can do so. The steps necessary are to reserve the physical address for the DMA device, and then map that address into a user mode process or driver address space, as shown below:
  1. In the "MEMORY" section of the Config.bib file, add a "RESERVED" section, as in the following example:

    ;name  hex start address  hex size in bytes   keyword RESERVED
    MY_DMA 8003000 00004000 RESERVED
    							

    This will reserve a 16-KB contiguous block of memory starting at address 8003000. By definition, any memory reserved with the RESERVED keyword is contiguous.

    ISR and kernel mode processes can then directly access this memory, but user mode drivers and applications must use the VirtualAlloc and VirtualCopy commands to map the memory into their address space.

    NOTE: From within your ISR, which runs in kernel mode, you can directly reference this memory.
  2. From a user mode application or driver you must use code similar to the following sample:
    pMem = VirtualAlloc(pStart, dwSize, MEM_RESERVE, PAGE_READWRITE);
    // pStart is the start of the virtual address range desired.
    // dwSize is the size in bytes of the region to access.
    // MEM_RESERVE indicates that the OS should reserve the address space but not back it with physical memory.
    // pMem will contain the pointer to the virtual memory block if the call is successful or NULL if it fails.<BR/>
    // now map the RESERVED memory to this address space:
    LPVOID pSrc = 8003000; // assign source to our RESERVED memory
    DWORD dwSize = 0x4000; // size of memory; from example bib entry above
    BOOL bRetCode; 
    bRetCode = VirtualCopy(pStart,pSrc/256, dwSize, PAGE_READWRITE | PAGE PHYSICAL,);
    
    // PAGE_PHYSICAL is necessary if pSrc is physical memory with a starting address above 0x1FFFFFFF 
    // When using PAGE_PHYSICAL it is also necessary to divide the source address by 256. 
    // bRetCode is TRUE for success, FALSE for failure.
    					
Device drivers can also use the MmMapIoSpace call to map physical memory. See the Platform Builder 3.0 Documentation for more information.

Modification Type:MinorLast Reviewed:8/18/2005
Keywords:kbhowto KB299355