為了測試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("\r\n--- Entering main() --- \r\n"); Config = XAxiDma_LookupConfig(DMA_DEV_ID); if (!Config) { xil_printf("No config found for %d\r\n", DMA_DEV_ID); return XST_FAILURE; } /* Initialize DMA engine */ XAxiDma_CfgInitialize(&AxiDma, Config); if(!XAxiDma_HasSg(&AxiDma)) { xil_printf("Device configured as Simple mode \r\n"); 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\r\n"); return XST_FAILURE; } Status = RxSetup(&AxiDma); if (Status != XST_SUCCESS) { xil_printf("Failed RX setup\r\n"); 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\r\n"); 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\r\n"); 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\r\n", 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\r\n"); goto Done; } } xil_printf("Sent Packet with Tdest 0 Successfully\n\r"); /* 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\r\n"); 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\r\n", 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\r\n"); 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\n\r"); xil_printf("AXI DMA SG interrupt Test passed\r\n"); Done: xil_printf("--- Exiting main() --- \r\n"); 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