If you never meet, maybe the mood will never be heavy if you miss it, you may not be able to take it easy in your life. A look is enough to xinhai the hurricane
A deeper understanding of the landscape in the barren land a journey is enough to haggard a weak heart
Every look at the eyes of the ripples will want to tears to death how can not leisurely love and how can not be indifferent
Just love each other once is a life without regrets
Maybe, never a day as bright as the future, maybe, never the day
Success as bright as the lights may, can only be so climbing but not reach the peak perhaps, can only be such a torrent but cannot lift the waves
Perhaps, we can give you only a vicissitudes heart and a full face of wind and frost
Maybe some things have been written well, maybe a heart has been doomed, just cheat yourself, she is still in love with you ~
DMA Overview
DMA is a hardware mechanism that allows two-way data transfer between peripherals and system memory without the need for a CPU to participate. It can get the system CPU out of the actual I/O data transfer process, greatly improve the throughput rate of the system, and during the transmission, the CPU can also perform other tasks concurrently.
DMA vs. Cache consistency
The cache acts as a buffer for the memory of the CPU, avoiding every time the CPU interacts with the relatively slow memory to improve the data access rate, and DMA can be used as a way to transfer data between memory and peripherals, and data does not require CPU turnover.
"Suppose the device driver fills some data into a memory buffer and then immediately commands the hardware device to read the data using DMA transfer." If the DMA accesses these physical RAM memory units, and the contents of the corresponding hardware cache rows are not written to RAM, the hardware device reads the old values in the memory buffers. ”
There are now two ways to handle DMA buffers: Consistent DMA mappings: the more abstract The book says, the plain is that any overwrite of the DMA buffer will be updated directly into memory, also known as "synchronous" or "consistent." Streaming DMA mapping: As a personal understanding, the flow here is the input and output stream, we need to specify the direction of the DMA buffer beforehand. Starting a streaming DMA data transfer is divided into the following steps (this DMA Driver Development Introduction is only suitable for s3c2410 processor type ): 1. Allocates a DMA buffer. In the case where the DMA device does not adopt the s/g (scatter/gather) mode, the buffer must be physically contiguous, and the Linux kernel has two functions to allocate contiguous memory: Kmalloc () and __get_free_pages (). Both functions have a maximum allocation of contiguous memory, Kmalloc in bytes allocated, a maximum of approximately 64kb,__get_free_pages () to allocate pages in units, a maximum number of pages to allocate 2^order, and the maximum value of the order parameter is determined by the include/ The Max_order macro in the Linux/mmzone.h file is determined (in the default 2.6.18 kernel version, the macro is defined as 10. That is, in theory the __get_free_pages function can apply up to 1<<10 * 4KB or 4MB of contiguous physical memory at a time, which is defined as 11 in the Xilinx ZYNQ Linux kernel. 2. Establish a streaming mapping after read and write access to the DMA flush, and before starting the DMA device transfer, enable the Dma_map_single () function to establish a streaming DMA mapping that takes the linear address of the buffer as its parameter and returns the corresponding bus address.
3. Release the streaming map call the Dma_unmap_single () function when we need to release the mapping after the DMA transfer is complete.
Note:(1). To avoid cache consistency issues, the driver should call the Dma_sync_single_for_device () function to flush the cache line corresponding to the DMA buffer before starting the DMA data transfer from RAM to the device, if necessary. (2). The device driver is not able to access the memory buffer until the DMA data transfer from device to RAM is complete, but if necessary, the driver should call the DMA_SYNC_SINGLE_FOR_CPU () function before reading the buffer to invalidate the corresponding hardware cache line. (3). Although the Kmalloc is implemented with __get_free_pages, the kmalloc corresponding release buffer function is Kfree, and the __get_free_pages corresponding release buffer function is free_pages. Several application and release functions that are related to __get_free_pages are as follows: Application function:
Alloc_pages (Gfp_mask,order) returns the address of the first assigned page box descriptor or returns NULL if the allocation fails. __get_free_pages (Gfp_mask,order) is similar to Alloc_pages (), but it returns the linear address of the first assigned page. If you need to obtain a page box number for a linear address, you need to call the Virt_to_page (addr) macro to produce a linear address.
Release function:
__free_pages (Page,order) The main emphasis here is that the page is to release the linear first address of the buffer where the box number Free_pages (Page,order) This function is similar to __free_pages (Page,order), But the parameter it receives is the linear address of the first page box to be freed addr
DMA drives The main data structure:
1)DMA single kernel buffer data structure:
typedef struct DMA_BUF_S {int size; /* Buffer size: Buffer sizes */dma_addr_t Dma_start; /* Starting DMA Address: Buffer start physical */int ref; /* Number of DMA references buffer start virtual address */void *id; /* To identify buffer from outside Mark */int write; /* 1:buf to write, 0:buf to read DMA read or write */struct dma_buf_s *next; /* Next buf to process refers to the downward buffer structure */} dma_buf_t;
2)DMA Register data structure:
/* DMA control register structure */typedef struct {volatile u_long disrc;/source Address register volatile u_long disrcc;//source Control Register volatile U _long didst;//Purpose Register volatile u_long didstc;//Purpose Control Register volatile U_long DCON;//DMA Control register volatile U_long dstat;// Status register volatile U_long dcsrc;//current source volatile u_long dcdst;//Current purpose volatile u_long dmasktrig;//trigger mask Register} dma_regs_t;
3)DMA device data structure
/* DMA device structre */typedef struct {dma_callback_t CALLBACK;//DMA after the completion of the callback function, call the U_long dst;//destination register content in the interrupt handling routine U_long src;//Source Register Content u_long ctl;//control Register content of this device u_long dst_ctl;//Purpose control Register contents u_long src_ctl;//source control register content} dma_device_t;
4)DMA channel data structure
/* DMA Channel structure */typedef struct {dmach_t channel;//channel number: can be 0,1,2,3unsigned int in_use; /* device is allocated */const char *device_id; /* Device name */dma_buf_t *head; /* Where to insert buffers The DMA channel buffer chain header */dma_buf_t *tail; /* Where to remove buffers the DMA channel buffer chain footer */dma_buf_t *curr; /* Buffer currently DMA ' ed the DMA channel buffer list in the current buffer */unsigned long queue_count; /* Number of buffers in the list of buffers */int active; /* 1 if DMA is actually processing data whether the channel is already using */dma_regs_t *regs; /* points to appropriate DMA registers the DMA control register */int IRQ used by the channel; /* IRQ used by the channel//channels application Interrupt number */dma_device_t write; /* to write//perform read operation of the DMA device */dma_device_t read; /* To read the DMA device that performs the write operation */} s3c2410_dma_t;
The main functions of DMA drive function analysis:
The main tasks of writing a DMA drive include:DMA Channel request,DMA interrupt request, control register settings, Mount DMA wait queue, clear DMA interrupt, Release DMA Channel.
int S3C2410_REQUEST_DMA (const char *device_id, dmach_t channel,dma_callback_t WRITE_CB, dma_callback_t READ_CB) ( S3c2410_dma_queue_buffer);
Function Description: Request a DMA resource for a channel , populate the contents of the s3c2410_dma_t data structure, and request a DMA interrupt.
Input parameters:device_id DMA device name; channel number;
WRITE_CB The callback function completed by the DMA write operation;READ_CB DMA read operation completed callback function
Output parameters: If channel channels are used, an error is returned; otherwise, 0 is returned.
int S3c2410_dma_queue_buffer (dmach_t channel, void *buf_id,dma_addr_t data, int size, int write) (s3c2410_dma_stop);
Function Description: This is the most critical function of the DMA operation, which completes a series of actions: Allocating and initializing a DMA kernel buffer control structure, inserting it into the DMA wait queue, setting the DMA control register content, waiting for DMA Action trigger
Input parameters: channel number;buf_id, buffer identifier
dma_addr_t Data DMA buffer starting physical address; size DMA data buffer sizes; write is written or read operations
Output parameter: Operation succeeded, return 0; otherwise, return error number
int S3c2410_dma_stop (dmach_t channel)
Function Description: Stops the DMA operation.
int S3c2410_dma_flush_all (dmach_t channel)
Function Description: Releases all memory resources requested by the DMA channel
void S3c2410_free_dma (dmach_t channel)
Function Description: Release DMA channel
Because the functions are powerful, a full DMA driver typically calls only the above 3 functions. You can call S3C2410_REQUEST_DMA in the driver initialization, call S3c2410_dma_queue_buffer before starting DMA transfer, release the driver module, call S3C2410_FREE_DMA.
All rights reserved, reprint please specify reprint address: http://www.cnblogs.com/lihuidashen/p/4470678.html
In layman's ~linux device-driven DMA