• 【原创】ZYNQ AXIDMA IP Multichannel mode开发日记


    为了测试AXI DMA IP的multi-channel mode,我们需要搭建一个简单的硬件平台。具体的硬件电路见下图:

     Diagram

    从上图可以看出,DMA的发送端和接收端都使用了两个通道。这两个通道之间通过data fifo做缓存,并且构成回路。由于AXI DMA IP的multi-channel mode的AXI4-stream接口通过TDEST、TID来区分不同的通道,因此需要AXI4-Stream Interconnect IP将两个AXI4-Stream接口“耦合”成一个AXI4-Stream接口。值得一提的是,data fifo的AXI4-Stream接口信号中必须包含TDEST、TID,否则无法区分出这两个通道。

    软件部分(SDK)很简单,配置玩两个发送和接口通道后就可以进行数据的收发了。数据收发的测试采用的方式是TX0 channel对应RX0 channel,TX1 channel对应RX1 channel,构成两对回路先后分别测试。main函数的内容如下:

    int main(void)
    {
        int Status;
        XAxiDma_Config *Config;
    
        /* Initial setup for Uart16550 */
    #ifdef XPAR_UARTNS550_0_BASEADDR
    
        Uart550_Setup();
    
    #endif
    
        xil_printf("
    --- Entering main() --- 
    ");
    
        Config = XAxiDma_LookupConfig(DMA_DEV_ID);
        if (!Config) {
            xil_printf("No config found for %d
    ", DMA_DEV_ID);
    
            return XST_FAILURE;
        }
    
        /* Initialize DMA engine */
        XAxiDma_CfgInitialize(&AxiDma, Config);
    
        if(!XAxiDma_HasSg(&AxiDma)) {
            xil_printf("Device configured as Simple mode 
    ");
            return XST_FAILURE;
        }
    
        /* Set up TX/RX channels to be ready to transmit and receive packets */
        Status = TxSetup(&AxiDma);
        if (Status != XST_SUCCESS) {
    
            xil_printf("Failed TX setup
    ");
            return XST_FAILURE;
        }
    
        Status = RxSetup(&AxiDma);
        if (Status != XST_SUCCESS) {
            xil_printf("Failed RX setup
    ");
            return XST_FAILURE;
        }
    
        /* Set up Interrupt system  */
        Status = SetupIntrSystem(&Intc, &AxiDma, TX_INTR_ID,
                        RX_INTR_ID, 1);
        if (Status != XST_SUCCESS) {
            xil_printf("Failed intr setup
    ");
            return XST_FAILURE;
        }
    
        /* Initialize flags before start transfer test  */
        TxDone = 0;
        RxDone = 0;
        Error = 0;
    
        /* Send a packet */
        Status = SendPacket(&AxiDma, TDEST0, TID0, PACKET0_DATA);
        if (Status != XST_SUCCESS) {
            xil_printf("Failed send packet
    ");
            return XST_FAILURE;
        }
    
        /*
         * Wait TX done and RX done
         */
        while (((TxDone < NUMBER_OF_BDS_TO_TRANSFER) ||
                (RxDone < NUMBER_OF_BDS_TO_TRANSFER)) && !Error) {
            /* NOP */
        }
    
        if (Error) {
            xil_printf("Failed test transmit%s done, "
                "receive%s done
    ", TxDone? "":" not",
                    RxDone? "":" not");
            goto Done;
        }else {
            /*
             * Test finished, check data
             */
    
    
    
    //        Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
    //                            RxPacket1, PACKET0_DATA);
            Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
                                RxPacket0, PACKET0_DATA);
    
    
    
    
    
            if (Status != XST_SUCCESS) {
                xil_printf("Data check failed
    ");
                goto Done;
            }
        }
    
        xil_printf("Sent Packet with Tdest 0 Successfully
    
    ");
    
        /* Initialize flags before start transfer test  */
        TxDone = 0;
        RxDone = 0;
        Error = 0;
    
        /* Send a packet */
        Status = SendPacket(&AxiDma, TDEST1, TID1, PACKET1_DATA);
        if (Status != XST_SUCCESS) {
            xil_printf("Failed send packet
    ");
            return XST_FAILURE;
        }
    
        /*
         * Wait TX done and RX done
         */
        while (((TxDone < NUMBER_OF_BDS_TO_TRANSFER) ||
            (RxDone < NUMBER_OF_BDS_TO_TRANSFER)) && !Error) {
            /* NOP */
        }
    
    
        if (Error) {
            xil_printf("Failed test transmit%s done, "
                    "receive%s done
    ", TxDone? "":" not",
                    RxDone? "":" not");
            goto Done;
        }else {
            /*
             * Test finished, check data
             */
    
    
    
    
    
    //        Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
    //                    RxPacket0, PACKET1_DATA);
            Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
                        RxPacket1, PACKET1_DATA);
    
    
    
    
    
            if (Status != XST_SUCCESS) {
                xil_printf("Data check failed
    ");
                goto Done;
            }
        }
    
        /* Disable TX and RX Ring interrupts and return success */
        DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);
    
        xil_printf("Sent Packet with Tdest 1 Successfully
    
    ");
    
        xil_printf("AXI DMA SG interrupt Test passed
    ");
    
    Done:
    
        xil_printf("--- Exiting main() --- 
    ");
    
        if (Status != XST_SUCCESS) {
            return XST_FAILURE;
        }
    
        return XST_SUCCESS;
    }

    测试结果(UART打印信息)如下:

    --- Entering main() ---
    Sent Packet with Tdest 0 Successfully

    Sent Packet with Tdest 1 Successfully

    AXI DMA SG interrupt Test passed
    --- Exiting main() ---

    原创声明:本文版权归 霸天虎1108 所有,转载请注明出处。

    本文标题:ZYNQ AXIDMA IP Multichannel mode开发日记

    本文网址:https://www.cnblogs.com/batianhu/p/zynq_axidma_multichannelmode_diary1.html

  • 相关阅读:
    Tensorflow2(预课程)---7.5、cifar10分类-层方式-卷积神经网络-VGG16
    卷积神经网络之AlexNet
    上传大型视频文件到服务器的控件
    上传大型视频文件到服务器的组件
    上传大型视频文件到服务器的工具
    Nginx上传大型视频文件到服务器,解决方案
    百度WebUploader上传大型视频文件到服务器,解决方案
    WebUploader上传大型视频文件到服务器,解决方案
    html5上传大型视频文件到服务器,解决方案
    jquery上传大型视频文件到服务器,解决方案
  • 原文地址:https://www.cnblogs.com/batianhu/p/zynq_axidma_multichannelmode_diary1.html
Copyright © 2020-2023  润新知