为了测试AXI DMA IP的multi-channel mode,我们需要搭建一个简单的硬件平台。具体的硬件电路见下图:
从上图可以看出,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