Direct Memory Access (Windows CE 5.0)

Send Feedback

Direct memory access (DMA) is a method of transferring data from a device to memory, from memory to a device, or from memory to memory, without the help of a microprocessor. You can perform common buffer and scatter/gather DMA using the CEDDK.dll or kernel functions. Common buffer DMA uses a contiguous buffer in main memory. Scatter/gather DMA uses multiple blocks at different memory addresses. For more information about the CEDDK.dll functions, see CEDDK Dynamic-Link Library.

A standard DMA transfer occurs when a DMA controller performs the transfer. A DMA bus master transfer occurs when a peripheral device performs the transfer. Microsoft recommends that you use the CEDDK.dll functions for DMA. The CEDDK.dll functions call the kernel functions. The following table compares two ways to perform DMA: using CEDDK.dll functions and using kernel functions.

Using CEDDK.dll functions Using kernel functions
CEDDK.dll provides these functions for obtaining a buffer for DMA transfers:

HalAllocateCommonBuffer

HalFreeCommonBuffer

HalTranslateSystemAddress

The kernel provides these functions for obtaining a buffer for DMA transfers:

AllocPhysMem

FreePhysMem

CEDDK.dll functions can handle bus and hardware platform-specific address translations. You must handle hardware platform-specific address translations. You can call HalTranslateSystemAddress to translate the address.
CEDDK.dll functions are seful for common buffer DMA. The kernel functions may be useful for scatter/gather DMA.
CEDDK.dll functions use a default memory alignment of 64 KB. The kernel functions allow you to DMA change the default memory alignment.

The CEDDK.dll functions handle address translations between the system and the PCI bus or ISA bus for the DMA controller. You can support other bus types. The CEDDK.dll functions translate a physical RAM address into the corresponding bus-relative physical address for the DMA controller. To set up a common buffer for bus master DMA using the CEDDK.dll functions, a bus master DMA device driver can call HalAllocateCommonBuffer with the DMA_ADAPTER_OBJECT structure.

The following code example shows a correct call to HalAllocateCommonBuffer. The code example is from the ES1371 driver located in %_WINCEROOT%\Public\Common\OAK\Drivers\WaveDev\PDD\ES1371 directory.

// Allocate an adapter object on the stack
DMA_ADAPTER_OBJECT AdapterObject; 
AdapterObject.ObjectSize = sizeof(AdapterObject); 
AdapterObject.InterfaceType = PCIBus; 
AdapterObject.BusNumber = 0; 

// Allocate a single paged 4 KB output buffer
dma_out_page[0] = (PUCHAR) HalAllocateCommonBuffer(&AdapterObject, 4096, &dma_out_logical_address, FALSE);

if (!dma_out_page[0]) { 
  ERRMSG("PDD_AudioInitialize: DMA Buffer Page Allocation Failed");
  return FALSE;
}

If the call to HalAllocateCommonBuffer succeeds, it returns the allocated buffer, or NULL if the call fails. The driver can use the allocated common buffer as a storage area for DMA transfers. The function also returns the physical bus-relative address of the buffer, which the function optionally provides to the DMA controller.

You can also use the AllocPhysMem and FreePhysMem kernel functions for common buffer DMA transfers. If you use the kernel functions, call HalTranslateSystemAddress to translate the address you are passing to the DMA controller to avoid a memory violation. These functions take an alignment parameter, the CEDDK.dll functions use default alignment of 64 KB. For a common buffer DMA example with the kernel functions, see the %_WINCEROOT%\Public\Common\Oak\Drivers\Usb\Hcd directory.

To set up scatter/gather DMA, you must use multiple pairs of base addresses and lengths simultaneously. The ATAPI driver located in the %_WINCEROOT%\Public\Common\Oak\Drivers\Block\Atapi directory is an example of scatter/gather DMA implementation.

See Also

CEDDK Dynamic-Link Library | HalFreeCommonBuffer

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.