1. 简介
linux下有现成的dw_dmac驱动,但是需要自己创建设备文件,分配IRQ和mem resources, 所以需要对配置进行测试
linux dma engine framework提供了dmatest.c测试文件,用于测试,但是怎么使用这个文件呢?module_param_string(name,string ,len,perm);
将变量name的内容拷贝到string中。(name代表我们在insmod时设置的参数 ,string是个内部参数),这样就可以给driver module传递参数
module_param(name,type,perm);
设置name的类型,将name export,这样可以在insmod时,改写这个参数值 、
dmatest.c的参数有:
parm:channel: | Bus ID of the channel to test (default: any) (string) |
parm:device: | Bus ID of the DMA Engine to test (default: any) (string) |
parm:iterations: | Iterations before stopping test (default: infinite) (uint) |
parm:max_channels: | Maximum number of channels to use (default: all) (uint) |
parm:pq_sources: | Number of p+q source buffers (default: 3) (uint) |
parm:test_buf_size: | Size of the memcpy test buffer (uint) |
parm:threads_per_chan: | Number of threads to start per channel (default: 1) (uint) |
parm:xor_sources: | Number of xor source buffers (default: 3) (uint) |
struct dma_chan *chan;
dma_addr_t dma_src;
dma_addr_t dma_dst;
char *src=dma_alloc_coherent(NULL,512,&dma_src,GFP_KERNEL);
char *dst=dma_alloc_coherent(NULL,512,&dma_dst,GFP_KERNEL);
int i=0;
for(i=0;i<512;i++){
*(src+i)='c';
}
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_MEMCPY, mask);
chan = dma_request_channel(mask,NULL,NULL);
struct dma_device *dev;
struct dma_async_tx_descriptor *tx=NULL;
enum dma_ctrl_flags flags;
dma_cookie_t cookie;
flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT
| DMA_COMPL_SKIP_DEST_UNMAP | DMA_COMPL_SRC_UNMAP_SINGLE;
dev=chan->device;
tx=dev->device_prep_dma_memcpy(chan,dma_dst,
dma_src,512,flags);
if(!tx){
printk(KERN_INFO "Failed to prepare DMA memcpy:%d\n",__LINE__);
}
tx->callback=dac_dma_complete_func;
tx->callback_param=NULL;
cookie=tx->tx_submit(tx);
if(dma_submit_error(cookie)){
printk(KERN_INFO "Failed to do DMA tx_submit:%d\n",__LINE__);
}
dma_async_issue_pending(chan);
return 0;