Post Go back to editing

iio_buffer_refill() to receive high speed contiguous buffer sample reads from ADRV9009 ADC

Category: Software
Product Number: ADRV9009-ZCU102
Software Version: Latest? 2023 - Kuiper Linux

I have a ZCU102 board with an ADRV9009.

We're trying to get 245MSps data onto an SSD, as we want to record several minutes of continuous, 245MSps data.

However I am finding that while using a modified iioStreaming_adrv9009 example code, just having iio_buffer_refill() in a loop (not writing the data anywhere yet) is taking much longer to cycle through than what it should take for the buffer to refill.
From my understanding of how the buffer rotations interact with the DMAC, it doesn't seem like the iio_buffer_refil() should block the program for very long once a buffer is filled, and the buffer would be quick to fill up.

I setup a timer to measure the time between the start and end of the loop, and the time taken pointed to an equivalent sample rate of ~13MSps (with gaps).
There should be 4 buffers of size 1024*1024.

I don't have the exact code I used on hand right now, but it was along the lines of:

while (!stop)
        ssize_t nbytes_rx, nbytes_tx;
        char *p_dat, *p_end;
        ptrdiff_t p_inc;

        // Refill RX buffer
        nbytes_rx = iio_buffer_refill(rxbuf);
        if (nbytes_rx < 0) { printf("Error refilling buf %d\n",(int) nbytes_rx); shutdown(); }

        // READ: Get pointers to RX buf
        p_inc = iio_buffer_step(rxbuf);
        p_end = iio_buffer_end(rxbuf);

        // Sample counter increment and status output
        nrx += nbytes_rx / iio_device_get_sample_size(rx);

Would using the IIO library be feasible to achieve this and we just have something that needs better configuration?

I considered this application might require a custom HDL configuration to DMA the ADC data into the PCIe SSD, but I was hopeful that this would not be required as I lack the experience to confidently implement this.
  • Hi,

    In *theory* there would be nothing that prevents you from transferring 245 MSPS from the IIO driver to a SSD, as long as the hardware can keep up.

    In practice, we are far from getting these numbers. The current version of libiio will memory-map the DMA buffers bypassing the cache, which means that reads and writes from/to the buffer are somewhat slow. The second problem, is actually reading/writing the data using the CPU in the first place, instead of just passing the DMA buffer to the SSD controller's built-in DMA, which slows things down a lot, especially with a weak CPU.

    We are working on upstreaming a new DMABUF interface to IIO drivers, which would allow you (through the new Libiio v1.0 API that's currently in the "dev" branch) to simply pass the DMABUFs to other drivers, without the data being copied at any moment. It still needs some work (it requires a scatter-gather-capable DMA HDL and driver, plus non-upstream kernel patches), and I don't think the filesystem subsystem of Linux supports DMABUFs yet, so there is still a lot of work to be done.

    For the short-term, I think your only option would be to handle this in HDL directly.



  • Hi  ,

    I found the solution to the first problem was just to ensure local_context was being loaded.
    This allowed the buffer_refill() to be executed fast enough in a tight loop where we are now able to continually refill the buffers at 250MSps.

    Though of course trying to then write the data to our NVMe SSD is performing quite slowly, which we hopefully can figure out.