Skip to content

Oscar Software Framework Manual Memory DMA Module

scs edited this page Jul 16, 2012 · 3 revisions

Go to Table of Contents.

Table of Contents

Memory DMA Module (dma)

Description

This module allows fast and easy control over the internal memory DMA units from user-space. It works in symbiosis to the open-source bfdma kernel module, written by Marc Hoffman. This module has to be inserted into the kernel for the module to function on the target. The only task of the module is to reserve the DMA channels and to register an exception handler, in which a descriptor-based DMA transfer is initiated. The framework module itself provides methods to easily assemble a chain of DMA descriptors and triggers the starting of the DMA by raising the exception the kernel module registered to handle. This is a much faster, since hardware-assisted, method than system calls for example, taking only 10s instead of 1000s of cycles. This is very important when wanting to copy small data chunks, as often is the case in image/video processing.

The DMA chains support 2D operation and consist of chains of several moves which are executed in a row. One first assembles all the moves in a chain, then starts the DMA transfer and then optionally has the possibility to synchronize execution to the end of the transfer.

Target Hardware Resource

Uses the onboard DMA controller of the Blackfin DSP. Specifically, it reserves the source and destination channel of the second Memory DMA (MDMA_S1 and MDMA_S2).

Dependencies

  • log: For logging.
  • sup: For cache coherency functions.

Usage

 OscDmaAllocChain(&hChain); /* (1) */
 
 OscDmaAdd1DMove(hChain, /* (2) */
     pDest, /* Destination pointer. */
     DMA_WDSIZE_16, /* Destination word size. */
     LENGTH, sizeof(uint32), /* Dest count and modify. */
     pSrc, /* Source pointer. */
     DMA_WDSIZE_16, /* Source word size. */
     LENGTH, sizeof(uint32)); /* Source count and modify. */
 
 OscDmaAdd2dMove(hChain, /* (3) */
     pDest2D, /* Destination pointer. */
     DMA_WDSIZE_32, /* Destination word size. */
     WIDTH, sizeof(uint32), /* Dest Xcount and Xmodify. */
     HEIGHT, OFFSET, /* Dest Ycount and Ymodify. */
     pSrc2D, /* Source pointer. */
     DMA_WDSIZE_32, /* Source word size. */
     WIDTH, sizeof(uint32), /* Source Xcount and Xmodify. */
     HEIGHT, OFFSET); /* Source Ycount and Ymodify. */
 
 OscDmaAddSyncPoint(hChain); /* (4) */
 OscDmaStart(hChain); /* (5) */
 
 /* Calculations. */
 
 OscDmaSync(hChain); /* (6) */
 
 
 OscDmaMemCpySync(hChain, pDest, pSrc, LENGTH); /* (7) */
 
  1. Allocate a DMA chain to write moves to.
  2. Add a 1-dimensional memory move of from pSrc to pDst with length LENGTH. In this case, only the lower 16 bits of each 32 bit number will be transferred (word size 16 but modify 4 bytes).
  3. Add a 2-dimensional memory move from pSrc2D to pDst2D. The difference to (3) is that an additional dimension exists so a second modify can be specified.
  4. Add a sync point to the chain. This is a token marking the end of a chain and necessary, if one wants to synchronize the execution to the end of the transfer.
  5. Start the DMA.
  6. Synchronize to the end of the DMA transfer. This will busy-wait until the DMA transfer is finished but only works if a sync point has been added to the end of the chain.
  7. This is shorthand for setting up a memory transfer of length LENGTH from source to destination. LENGTH has to be a multiple of 4 bytes though.
Clone this wiki locally