Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Help me understand the operation of the NRF_RINGBUF module

Hi!

I'm trying to figure out the nrf_ringbuf module, and would really appreciate some advice about its intended use case. The api exposes the following functions:


void 	nrf_ringbuf_init (nrf_ringbuf_t const *p_ringbuf)
 
ret_code_t 	nrf_ringbuf_alloc (nrf_ringbuf_t const *p_ringbuf, uint8_t **pp_data, size_t *p_length, bool start)
 
ret_code_t 	nrf_ringbuf_put (nrf_ringbuf_t const *p_ringbuf, size_t length)
 
ret_code_t 	nrf_ringbuf_cpy_put (nrf_ringbuf_t const *p_ringbuf, uint8_t const *p_data, size_t *p_length)
 
ret_code_t 	nrf_ringbuf_get (nrf_ringbuf_t const *p_ringbuf, uint8_t **pp_data, size_t *p_length, bool start)
 
ret_code_t 	nrf_ringbuf_free (nrf_ringbuf_t const *p_ringbuf, size_t length)
 
ret_code_t 	nrf_ringbuf_cpy_get (nrf_ringbuf_t const *p_ringbuf, uint8_t *p_data, size_t *p_length)


This is my current flow of execution:

Ask for space with nrf_ringbuffer_alloc( p_ringbuf, pp_data, p_length, false). This gives me a pointer to where I can write the amount of bytes that I've requested.

Write bytes to the allocated pointer location using memcpy( pp_data, inputBuffer, length )

Commit the bytes to the ring buffer using nrf_ringbuf_put( p_ringbuf, length)

...

Later pop things from the ring buffer using:

nrf_ringbuf_get ( p_ringbuf, pp_data, &length, false );

memcpy( inputBuffer, pp_data, length );

nrf_ringbuf_free( p_ringbuf, length );

However, I am getting an error, NRF_ERROR_INVALID_STATE, from line 94 of nrf_ringbuf.c:

 if (nrf_atomic_u32_fetch_sub(&p_ringbuf->p_cb->flag, 1 << WR_OFFSET) & (1 << WR_OFFSET))

I believe I am not using the api correctly, as I haven't understood the use case of nrf_ringbuf_cpy_put() and cpy_get() . Are these supposed to be called in-between alloc & put, and get & free? It is not very clear in the documentation. Please advise.


Cheers and all the best,
Rares Gosman

  • Hey Rares,
    I believe you are using the API correctly. The library is experimental, and I see there's some changes between SDK14.0 and 14.2. Try 14.2 and see if that helps. 
     
    The 'copy' calls is used when you want the library to read and write directly to another buffer, instead of the one provided by the buffer allocation call.  

    Cheers,

    Håkon.

  • Hi Hakon,

    Thanks for the advice. I updated to SDK14.2 and kept running into the same issue. I realized it was a problem with the nrf_ringbuf_cpy_get() function. The syntax being used with memcpy() is incorrect. It is provided like so in the SDK:

        if (length > trail)
        {
            memcpy(&p_ringbuf->p_buffer[masked_rd_idx], p_data, trail);
            length -= trail;
            masked_rd_idx = 0;
            p_data += trail;
        }
        memcpy(p_data, &p_ringbuf->p_buffer[masked_rd_idx], length);
        p_ringbuf->p_cb->rd_idx += *p_length;


    Since this is a get() function, it should be filling the user-provided p_data buffer with data from the ring buffer. However, in this section of the code, where it handles the wrap-around behavior, the first memcpy() call is copying blank data from p_data into the ring buffer, and overwriting valid data. Line 212 of "nrf_ringbuf.c" should be:

    memcpy(p_data, &p_ringbuf->p_buffer[masked_rd_idx], trail);

    On the other hand, the nrf_ringbuf_cpy_put() command is fine:

        if (length > trail)
        {
            memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, trail);
            length -= trail;
            masked_wr_idx = 0;
            p_data += trail;
        }
        memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, length);
        p_ringbuf->p_cb->wr_idx += *p_length;

    Notice that both memcpy() calls are being executed with the same order of parameters, since the destination is the ring buffer in the event of a put() command.

    Please notify those in charge of this section of the SDK of this error.

    Cheers,
    Rares Gosman 

  • I've reported the issue to the developers, but we might have to wait a while for a comment. 

  • Hi Håkon,
    Just wanted to follow up with you on this issue. I see that the change hasn't been made in SDK15, which launched last week. Is there any word back from the developer?

    Cheers,
    Rares

Related