XDMA stream mode eop_flush
Hello everyone, I’m currently encountering some issues when using XDMA in stream mode. On the FPGA side, I use an AXIS stream generator module, which continuously produces 16,384 bytes of data through the valid and ready handshake, and asserts tlast for the last beat.
On the host side, my test program is as follows:
int main() {
int status = 0;
char rx_buf[1024*1024] = {0};
int c2h0 = open("/dev/xdma0_c2h_0", O_RDWR | O_TRUNC);
if (c2h0 < 0){
fprintf(stderr, "unable to open device %s.\n", "/dev/xdma0_c2h_0");
status = -1;
}
for (size_t i = 0; i < 10000; i++)
{
int count = read(c2h0, rx_buf, 512*1024);
printf("actual recv size :%d\r\n", count);
}
close(c2h0);
return 0;
}
As expected, I should be able to receive a fixed-length data block each time. However, in reality, the read function does not return a fixed length each time.
actual recv size :15408
actual recv size :13168
actual recv size :16960
actual recv size :14640
actual recv size :12672
actual recv size :11776
actual recv size :44112
actual recv size :11472
actual recv size :14656
actual recv size :12400
actual recv size :12832
actual recv size :12976
actual recv size :17248
actual recv size :13664
actual recv size :13424
actual recv size :11376
actual recv size :44208
actual recv size :11440
eop_flush is pretty much pointless for C2H devices, so don't use it, especially when you try to download multiple packets in single transfer. The transfer is split into descriptors on page boundaries, which typically wouldn't coincide with packet boundaries. According to docs tlast would cause XDMA to ignore the rest of a descriptor and start with the next. This amount of the data would then miss in the next packet.
Simply download multiple of you packet length (without O_TRUNC).
If you wanted to use it badly (although I don't see any benefit in doing so), you could try to align your read buffer to PAGE_SIZE
Thank you for your reply. I really do want to use XDMA in stream mode. My application scenario is to transfer the received ADC data to the HOST.
Previously, I used my own packet mode, where the FPGA, under the control of the host, generated a data packet and then sent it to the host via the XDMA C2H channel. In that case, EOP_Flush was able to correctly obtain each IQ data packet.
However, when I set the FPGA side to stream mode (that is, continuously generating data packets of a fixed length) and then transmit them to the HOST through the C2H channel, this problem occurs
You can use AXI-Stream mode, there is no problem in that. The problem is the XDMA packet mode with O_TRUNC flag. It doesn't work like you want/need it.
That's why I suggest following:
- Put a FIFO capable to accommodate several packets in front of the relevant AXIS_C2H input.
- Remove
O_TRUNCfrom your code - Download single or multiple number of your packets.
That would download exactly requested amount of data (assuming it was produced within timeout period)