dma传输与memcpy传输对比测试结果分析。。。

1.测试代码,如下,网上找的,驱动的环境搭建之前/* * DMA test module * * Copyright (C) 2007 KEDACOM Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU
摘要由CSDN通过智能技术生成

本来拟定是想直接在x86的服务器上测试,但是发现执行时一直获取不到dma通道,只能在arm架构下尝试。
1.测试代码,如下,网上找的,驱动的环境搭建之前

/*
 * DMA test module
 *
 * Copyright (C) 2007 KEDACOM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/highmem.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/async_tx.h>
#include <linux/jiffies.h>

#define XFER_TIMES 4000 
#define XFER_LEN  1<<20

void *dma_src,*dma_dest;
struct dma_chan *chan = NULL;

static int __init dmatest_init(void)
{

    int xfer_order = get_order(XFER_LEN);
    int i,ret ;
    dma_cap_mask_t mask;
    dma_cookie_t cookie;
    enum dma_status status;
    u64 j1,j2;

    dma_src = __get_free_pages(GFP_KERNEL | GFP_DMA, xfer_order);
    if (!dma_src) {
        printk(KERN_ALERT "dma_src :alloc memory fail.n");
        ret = -ENOMEM;
        goto CLEAN;

    }

    dma_dest = __get_free_pages(GFP_KERNEL | GFP_DMA, xfer_order);
    if (!dma_dest) {
        printk(KERN_ALERT "dma_dest :alloc memory fail.n");
        ret = -ENOMEM;
        goto CLEAN;
    }
    printk(KERN_NOTICE"dma_src=%#x,dma_dest=%#xn",dma_src,dma_dest);    
    dma_cap_zero(mask);
    dma_cap_set(DMA_MEMCPY, mask);
    chan = dma_request_channel(mask, NULL, NULL);

    if (chan) {
        printk(KERN_NOTICE "dma_request_channel ok,current channel is : %
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于DMA(Direct Memory Access,直接内存访问)传输在不占用CPU时间的情况下,能够实现高速的数据传输,因此在一些需要高速数据传输的系统中经常会使用DMA技术。下面是使用DMA传输存储数据的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #define SRC_ADDR 0x20000000 // 源数据地址 #define DST_ADDR 0x30000000 // 目标数据地址 #define DMA_ADDR 0x40000000 // DMA控制器地址 // DMA控制器寄存器地址偏移量 #define DMA_SRC_ADDR 0x00 #define DMA_DST_ADDR 0x04 #define DMA_LEN_ADDR 0x08 #define DMA_CONTROL_ADDR 0x0C // DMA控制器寄存器位掩码 #define DMA_CONTROL_EN (1 << 0) // 使能位 #define DMA_CONTROL_DIR (1 << 1) // 方向位,0表示从源地址到目标地址,1表示从目标地址到源地址 #define DMA_CONTROL_MODE (1 << 2) // 工作模式,0表示单次传输,1表示循环传输 // 映射物理地址到虚拟地址 void* map_phys_addr(unsigned int addr, unsigned int size) { int fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd < 0) { perror("open /dev/mem failed"); exit(-1); } void* virt_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr); if (virt_addr == MAP_FAILED) { perror("mmap failed"); exit(-1); } close(fd); return virt_addr; } int main() { // 映射DMA控制器的物理地址到虚拟地址 void* dma_addr = map_phys_addr(DMA_ADDR, 0x1000); // 初始化源数据 unsigned char src_data[1024]; for (int i = 0; i < 1024; i++) { src_data[i] = i % 256; } // 映射源数据和目标数据的物理地址到虚拟地址 void* src_addr = map_phys_addr(SRC_ADDR, 1024); void* dst_addr = map_phys_addr(DST_ADDR, 1024); // 将源数据拷贝到物理地址 memcpy(src_addr, src_data, 1024); // 配置DMA控制器 *(unsigned int*)(dma_addr + DMA_SRC_ADDR) = SRC_ADDR; *(unsigned int*)(dma_addr + DMA_DST_ADDR) = DST_ADDR; *(unsigned int*)(dma_addr + DMA_LEN_ADDR) = 1024; *(unsigned int*)(dma_addr + DMA_CONTROL_ADDR) = DMA_CONTROL_EN | DMA_CONTROL_DIR | DMA_CONTROL_MODE; // 等待DMA传输完成 while (*(unsigned int*)(dma_addr + DMA_CONTROL_ADDR) & DMA_CONTROL_EN) { // 空循环 } // 检查目标数据是否与源数据相同 if (memcmp(src_data, dst_addr, 1024) == 0) { printf("DMA transfer succeed.\n"); } else { printf("DMA transfer failed.\n"); } // 解除映射 munmap(dma_addr, 0x1000); munmap(src_addr, 1024); munmap(dst_addr, 1024); return 0; } ``` 上述示例代码的主要步骤如下: 1. 使用`map_phys_addr`函数将DMA控制器、源数据和目标数据的物理地址映射到虚拟地址。 2. 初始化源数据,并将源数据拷贝到源数据物理地址上。 3. 配置DMA控制器的源地址、目标地址、传输长度和控制寄存器。 4. 等待DMA传输完成。 5. 检查目标数据是否与源数据相同。 6. 解除映射。 在实际应用中,需要根据具体的硬件平台和数据传输需求来编写相应的DMA传输代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值