Explicitly Flushing Asynchronous Streams

Questions and discussions about the Xillybus IP core and drivers

Explicitly Flushing Asynchronous Streams

Postby danielyxie »

Hi,
We are currently working on the CentOS 7 Linux distribution, and are trying to explicitly flush asynchronous downstreams. We are following the Xillybus host programming guide and using a zero length write():

Code: Select all
    while (1) {
        rc = write(xb_struct.fdw32, NULL, 0);

        if ( (rc < 0) && (errno == EINTR)) {
            continue;
        }

        if (rc < 0) {
            perror("write() failed");
            break;
        }

        break;    //flush successful
    }


Calling this function gives the following error:

Code: Select all
write() failed : Bad Address


It seems that it is possible to configure a program to allow zero-length writes using ioctl(), but we are unable to figure out how to do this on the CentOS7 Linux distribution. Any help would be greatly appreciated. Thanks!
danielyxie
 
Posts: 4
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby support »

Hello,

This is a bit odd. I would suggest supplying a non-NULL address to the write() call. Just any pointer to something that is allocated in memory. It looks like your kernel and/or glibc runs a sanity check on that argument.

Regards,
Eli
support
 
Posts: 802
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby danielyxie »

Hi Eli,

Thanks for the reply.

I've followed your suggestion but the program still returns the same error.

Code: Select all
    int rc;
    int buf[1];
    buf[0] = 1;

    while (1) {
        rc = write(xb_struct.fdw32, (void *) buf, 0);

        if ( (rc < 0) && (errno == EINTR)) {
            continue;
        }

        if (rc < 0) {
            perror("write() failed");
            break;
        }

        break;    //flush successful
    }


Something interesting we just noticed is that this error only occurs on the 32 bit stream, but not on the 8 bit stream. So, with:

Code: Select all
    xb_struct.fdw32 = open("/dev/xillybus_write_32", O_WRONLY);
    xb_struct.fdw8 = open("/dev/xillybus_write_8", O_WRONLY);


Calling

Code: Select all
rc = write(xb_struct.fdw8, (void *)buf, 0);


does not return any errors while calling

Code: Select all
rc = write(xb_struct.fdw32, (void *)buf, 0);


returns the write failed(): Bad Address error
danielyxie
 
Posts: 4
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby support »

Hello,

Could you please verify that there's indeed such a difference between a 32-bit stream and an 8-bit stream? And if so, how many bytes have you previously written in each of the cases when the zero-write call is issued? Could it be, by any chance, a number that doesn't divide by 4 on the 32-bit stream case?

Regards,
Eli
support
 
Posts: 802
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby danielyxie »

Hi Eli,

There is definitely this difference between the 32-bit stream and the 8-bit stream.

For both streams, the zero-write function is being called after writing 144 bytes, so it is divisible by 4.
danielyxie
 
Posts: 4
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby support »

Hello,

Could you please try a little change in the driver?

In xillybus_core.c, function xillybus_write(), line 1412, it goes:

Code: Select all
            } else {
               unsigned char *tail;
               int i;

               end_offset_plus1 = bufpos >>
                  channel->log2_element_size;

Please add one line, and change it to:
Code: Select all
            } else {
               unsigned char *tail;
               int i;

               howmany = 0;

               end_offset_plus1 = bufpos >>
                  channel->log2_element_size;


And then recompile & reinstall the driver. Please tell me if there's a difference.

Thanks,
Eli
support
 
Posts: 802
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby danielyxie »

Hi Eli,

This seems to have done the trick, it looks as if flushing is working properly and does not post any errors. Thanks for the help!

However, we have run into another issue. Would you mind offering any guidance on that?

We are generating a 144-byte packet on a host computer and sending 100 copies of this packet through Xillybus to a Virtex-7 FPGA. For some reason, only 36 of these packets are received by the FIFO on the FPGA, which we have verified using a debug core and a packet capture device. So 64 packets are being dropped somewhere before the FIFO and we are unsure where or why. Also, when sending 100 packets, the number of packets that are successfully transmitted is always 36.

The code for this consists of a for loop that executes 100 times:

Code: Select all
   
for(i = 0; i < 100; i ++) {
        sendUDPPacket(data, 90, sourceip, destip, destPort);
}


where the sendUDPPacket() function consists of a single write() call.
danielyxie
 
Posts: 4
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby support »

Hello,

It's good to know that fixed the zero-write call. I'll update the driver soon with this change.

As for your current issue: Assuming that the FIFO in the FPGA is connected correctly to the Xillybus IP core (in particular, the "full" port) no data is lost in the link between the host and the FIFO. But if the FIFO is full, the data transaction halts until there's room for more. I have to admit that 144 bytes times 36 doesn't sound like the size of a FIFO to me, so my best guess is that there's something with the "full" signal.

Regards,
Eli
support
 
Posts: 802
Joined:

Re: Explicitly Flushing Asynchronous Streams

Postby support »

IMPORTANT

It turns out that even before this fix, the driver flushed the stream properly. The only problem was that it returned an error code instead of 0.

This fix is now included in the driver available for download at the site (modinfo version 1.10). The driver for Windows was never affected by this issue.

Eli
support
 
Posts: 802
Joined:


Return to Xillybus