1、在用户设备树中 pl-custom中

/delete-node/ &axi_dma_0;
/ {
	axi_dma_0: dma@a0000000 {
		#dma-cells = <1>;
		clock-names = "s_axi_lite_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk";
		clocks = <&zynqmp_clk 71>, <&zynqmp_clk 71>, <&zynqmp_clk 71>;
		compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a";
		interrupt-names = "mm2s_introut", "s2mm_introut";
		interrupt-parent = <&gic>;
		interrupts = <0 89 4 0 90 4>;
		reg = <0x0 0xa0000000 0x0 0x10000>;
		xlnx,addrwidth = <0x20>;
		xlnx,sg-length-width = <0x1a>;
		dma-channel@a0000000 {
			compatible = "xlnx,axi-dma-mm2s-channel";
			dma-channels = <0x1>;
			interrupts = <0 89 4>;
			xlnx,datawidth = <0x10>;
			xlnx,device-id = <0x0>;
			xlnx,include-dre ;
		};
		dma-channel@a0000030 {
			compatible = "xlnx,axi-dma-s2mm-channel";
			dma-channels = <0x1>;
			interrupts = <0 90 4>;
			xlnx,datawidth = <0x10>;
			xlnx,device-id = <0x1>;
			xlnx,include-dre ;
		};
	};	
};

2 、在用户system-user中

/include/ "system-conf.dtsi"
/include/ "pl-custom.dtsi"
/ {
	axidma_chrdev: axidma_chrdev@0 {
    		compatible = "xlnx,axidma-chrdev";
    		dmas = <&axi_dma_0 0 &axi_dma_0 1>;
    		dma-names = "tx_channel", "rx_channel";
	};
};

&axi_dma_0 {
	dma-coherent;
	status = "okay";
};

3、device-tree.bbappend

SRC_URI += "file://system-user.dtsi"
SRC_URI += "file://pl-custom.dtsi"

4 、teminal

 petalinux-create -t modules -n xilinx-axidma --enable

5 、github上下载dma驱动,xilinx_axidma-master.zip 并解压,由于内核的改变,对下列部分文件做出改变。
(1) makefile

DRIVER_NAME = xilinx-axidma
$(DRIVER_NAME)-objs = axi_dma.o axidma_chrdev.o axidma_dma.o axidma_of.o
obj-m := $(DRIVER_NAME).o

(2)xilinx-axidma.bb

SRC_URI = "file://Makefile \ 
           file://axi_dma.c \
           file://axidma_chrdev.c \
           file://axidma_dma.c \
           file://axidma_of.c \
           file://axidma.h \
           file://axidma_ioctl.h \
           file://COPYING \

(3)axi_dma.c

#include <linux/of_dma.h>           // new

(4)axidma_chrdev.c
linux 内核4.x到5.x,参数减少,查看内核函数,无影响
https://elixir.bootlin.com/linux/v4.9.251/source/include/linux/of_device.h
https://elixir.bootlin.com/linux/v4.9.251/source/include/linux/uaccess.h

在 static bool axidma_access_ok(const void __user *arg, size_t size, bool readonly)函数中
// if (!readonly && !access_ok(VERIFY_WRITE, arg, size)) {
    if (!readonly && !access_ok(arg, size)) {
    // } else if (!access_ok(VERIFY_READ, arg, size)) {
    } else if (!access_ok(arg, size)) {
//of_dma_configure(struct device->dev, NULL);
of_dma_configure(struct device->dev, NULL,true);

(5)axidma_dma.c

#include <linux/of_dma.h>           // new
static void axidma_dma_callback(void *data)
	struct kernel_siginfo sig_info;

6、petalinux-build petalinux-build --sdk petalinux-package --sysroot
7、配置qt的环境。
8 qt 将example中的axidma_benchmark.c复制到qt,并添加其他所需文件。
(1)**.pro

SOURCES += \
    gpio.cpp \
    libaxidma.c \
    main.cpp \
    util.c

HEADERS += \
    axidma_ioctl.h \
    conversion.h \
    gpio.h \
    libaxidma.h \
    util.h

(2)main.cpp() 由于是将C文件改为c++文件,所以此文件中这个函数需要做改变((void *)和(char *)相同)

static int single_transfer_test(axidma_dev_t dev, int tx_channel, void *tx_buf,
        int tx_size, struct axidma_video_frame *tx_frame, int rx_channel,
        void *rx_buf, int rx_size, struct axidma_video_frame *rx_frame)
{
    int rc;

    // Initialize the buffer region we're going to transmit
    init_data((char *)tx_buf, (char *)rx_buf, tx_size, rx_size);

    // Perform the DMA transaction
    rc = axidma_twoway_transfer(dev, tx_channel, (char *)tx_buf, tx_size, tx_frame,
            rx_channel, (char *)rx_buf, rx_size, rx_frame, true);
    if (rc < 0) {
        return rc;
    }

    // Verify that the data in the buffer changed
    return verify_data((char *)tx_buf, (char *)rx_buf, tx_size, rx_size);
}

(3)在所有的 **.h中,为了使用QT的类功能,尽量用C++编程,对C文件的头文件做如下改变。

#ifdef  __cplusplus
extern "C"{
#endif

......

#endif /* UTIL_H_ */

#ifdef  __cplusplus
}
#endif

9、加载驱动

root@u3_save:/lib/modules/5.4.0-xilinx-v2020.1/extra# insmod xilinx-axidma.ko 
[ 1637.846215] axidma: axidma_dma.c: axidma_dma_init: 725: DMA: Found 1 transmit channels and 1 receive channels.
[ 1637.856240] axidma: axidma_dma.c: axidma_dma_init: 727: VDMA: Found 0 transmit channels and 0 receive channels.

10、测试 因为dma的输入输出并没有还起来,所以只能看到发出去,看不到接收的

root@u3_save:/mnt# ./u3_dma_save 
AXI DMA Benchmark Parameters:
	Transmit Buffer Size: 7.91 MiB
	R[ 1661.465441] axidma axidma: DMA mask not set
eceive Buffer Size: 7.91 MiB
	Number of DMA Transfers: 1000 transfers

Using transmit channel 0 and receive channel 1.
[ 1671.710879] axidma: axidma_dma.c: axidma_start_transfer: 309: DMA receive transaction timed out.
[ 1672.719678] xilinx-vdma a0000000.dma: Cannot stop channel 00000000145aa465: 0
Failed to perform the AXI DMA read-write transfer: Timer expired

11、当使用环回时

root@u3_dma_test:/# ./mnt/u3_dma_save   
AXI DMA Benchmark Parameters:
	Transmit Buffer Size: 7.91 MiB
	Receive Buffer Size: 7.91 MiB
	Number of DMA Transfers: 1000 transfers

Using transmit channel 0 and receive channel 1.
Single transfer test successfully completed!
Beginning performance analysis of the DMA engine.

DMA Timing Statistics:
	Elapsed Time: 41.49 s
	Transmit Throughput: 190.66 MiB/s
	Receive Throughput: 190.66 MiB/s
	Total Throughput: 381.32 MiB/s
root@u3_dma_test:/# 

13、qt and opencv 的配置
(1)安装sdk.sh
(2)在qt的pro中添加

INCLUDEPATH += /home/lcl/Soft/Sdk/sysroots/aarch64-xilinx-linux/usr/include

LIBS += \
    -lopencv_imgcodecs \
    -lopencv_highgui \
    -lopencv_imgproc \
    -lopencv_core \

即可。

14、接口改为128

root@u3_dma_test:/# ./mnt/u3_dma_save 
AXI DMA Benchmark Parameters:
	Transmit Buffer Size: 16.00 MiB
	Receive Buffer Size: 16.00 MiB
	Number of DMA Transfers: 1000 transfers

Using transmit channel 0 and receive channel 1.
	Elapsed Time: 0.25 s
Single transfer test successfully completed!
Beginning performance analysis of the DMA engine.

DMA Timing Statistics:
	Elapsed Time: 12.39 s
	Transmit Throughput: 1291.32 MiB/s
	Receive Throughput: 1291.32 MiB/s
	Total Throughput: 2582.65 MiB/s
root@u3_dma_test:/# 

15、第一个Elapsed Time: 0.25 s是当我把数据从缓冲区复制到其他位置消耗的时间,也就是16MB的数据需要250ms的时间,速率也就在60M左右,也验证以前的贴子,dma的实现方式(UIO或者内核驱动)与数据从缓冲区copy到别的地方的速率是没有关系的。
16、速度慢是缓冲区的问题 https://github.com/bperez77/xilinx_axidma/issues/69
(1)在设备树中

/include/ "system-conf.dtsi"
/include/ "pl-custom.dtsi"
/ {
	
	axidma_chrdev: axidma_chrdev@0 {
    		compatible = "xlnx,axidma-chrdev";
    		dmas = <&axi_dma_0 0 &axi_dma_0 1>;
    		dma-names = "tx_channel", "rx_channel";
		dma-coherent;
	};
&axi_dma_0 {
	dma-coherent;
	status = "okay";
};
在测试代码中加速加入测速代码
......
    rc = single_transfer_test(axidma_dev, tx_channel, tx_buf, tx_size,
            tx_frame, rx_channel, rx_buf, rx_size, rx_frame);
    if (rc < 0) {
        goto free_rx_buf;
    }

    struct timeval start_time0, end_time0;
    double elapsed_time0;
    // Begin timing
    gettimeofday(&start_time0, NULL);
    memcpy(image_mid0, rx_buf, 2048*4096*4);
    gettimeofday(&end_time0, NULL);
    elapsed_time0 = TVAL_TO_SEC(end_time0) - TVAL_TO_SEC(start_time0);
    printf("\tElapsed Time0: %0.2f s\n", elapsed_time0);

    struct timeval start_time1, end_time1;
    double elapsed_time1;
    // Begin timing
    gettimeofday(&start_time1, NULL);
    memcpy(image_mid1, image_mid0, 2048*4096*4);
    gettimeofday(&end_time1, NULL);
    elapsed_time1 = TVAL_TO_SEC(end_time1) - TVAL_TO_SEC(start_time1);
    printf("\tElapsed Time1: %0.2f s\n", elapsed_time1);

(3)测试结果

root@u3_dma_test:/# ./mnt/u3_dma_save 
AXI DMA Benchmark Parameters:
	Transmit Buffer Size: 32.00 MiB
	[   84.709677] axidma axidma: DMA mask not set
Receive Buffer Size: 32.00 MiB
	Number of DMA Transfers: 1000 transfers

Using transmit channel 0 and receive channel 1.
	Elapsed Time0: 0.07 s
	Elapsed Time1: 0.07 s
Single transfer test successfully completed!
Beginning performance analysis of the DMA engine.

DMA Timing Statistics:
	Elapsed Time: 24.75 s
	Transmit Throughput: 1292.82 MiB/s
	Receive Throughput: 1292.82 MiB/s
	Total Throughput: 2585.64 MiB/s
root@u3_dma_test:/# 

最后测得速率 32MB/70ms=450MB。
17、虽然速度是提高了,但是读写的数据是不对的
https://forums.xilinx.com/t5/%E5%B5%8C%E5%85%A5%E5%BC%8F-%E7%A1%AC%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91/%E5%88%86%E4%BA%AB-MPSoC%E9%80%BB%E8%BE%91%E5%8A%A0%E9%80%9F%E6%A8%A1%E5%9D%97%E6%95%B0%E6%8D%AE%E9%80%9A%E9%81%93%E5%BF%AB%E9%80%9F%E8%AE%BE%E8%AE%A1/m-p/1044098
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842098/Zynq+UltraScale+MPSoC+Cache+Coherency

Logo

更多推荐