This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to use the ring buffer library?

Hi!

I'm trying to implement a traditional ring buffer with the nrf_ringbuf library. I'm using nRF52840 DK with SDK 15.3.0 and SES.

I'm going to receive strings of data from UART and I will have up to something like 100 strings of data. I want the ring buffer to work so that I always have access to the newest data and the oldest ones are disgarded. It seems that this library should work for this, but somehow the ring buffer doesn't seem to overwrite when it's full. Am I using it wrong? My code is below, and it seems to me the buffer should now contain 9,10,11,12,5,6,7,8 and not 1,2,3,4,5,6,7,8.

NRF_RINGBUF_DEF(m_ringbuf, 8);

int main(void)
{
nrf_ringbuf_init(&m_ringbuf);

// test of ring buffer
    ret_code_t err_code;                                                 // save error code
    uint8_t data1_in[] = {1,2,3,4};                                      // "data in"
    uint8_t data2_in[] = {5,6,7,8};                                      // "data in"
    uint8_t data3_in[] = {9,10,11,12};                                   // "data in"
    uint8_t data_out[8];                                                 // "data out"

    size_t  len_in  = sizeof(data1_in);                                  // "data in" length
    size_t  len_out = sizeof(data_out);                                  // "data out" length

    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data1_in, &len_in);       // put data in ring buffer
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data2_in, &len_in);       // put data in ring buffer
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data3_in, &len_in);       // put data in ring buffer

    err_code = nrf_ringbuf_cpy_get(&m_ringbuf, data1_out, &len_out);     // get data from ring buffer
    
    printf("\n\nRing buffer contains:\n");
    for(int i = 0; i < len_out; i++)
      printf("%i\n", data1_out[i]);

}

Also, since I'm going to be using a multidimensional array for storing this data, is it a bad idea to even use the ring buffer library? Should I just construct my own?

Thanks!

Parents
  • Hi Marius!

    The ring buffer implementation in the SDK does not overwrite old data unless the buffer has been read, so for example 

    ret_code_t err_code;                                                
    uint8_t data1_in[] = {1,2,3,4};                                     
    uint8_t data2_in[] = {5,6,7,8};                                     
    uint8_t data3_in[] = {9,10,11,12};                                  
    uint8_t data1_out[4]; 
    uint8_t data2_out[8]; 
    
    size_t  len_in   = sizeof(data1_in);                                 
    size_t  len1_out = sizeof(data1_out);                                
    size_t  len2_out = sizeof(data2_out);                                
    
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data1_in, &len_in);       
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data2_in, &len_in);       
    err_code = nrf_ringbuf_cpy_get(&m_ringbuf, data1_out, &len1_out);    
    	
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data3_in, &len_in);       
    err_code = nrf_ringbuf_cpy_get(&m_ringbuf, data2_out, &len2_out);    

    will give you the output

    This can be further confirmed bu examining the implementation of the nrf_ringbuf_cpy_put function in the /components/libraries/nrf_ringbuf.c file. Here, the function calculates available space based in the stored read and write index (rd_idx, wr_idx).

    I would suggest using the queue library instead. If you enable NRF_QUEUE_MODE_OVERFLOW, the queue, if full, will overwrite the oldest element.

    Best regards,

    Heidi

Reply
  • Hi Marius!

    The ring buffer implementation in the SDK does not overwrite old data unless the buffer has been read, so for example 

    ret_code_t err_code;                                                
    uint8_t data1_in[] = {1,2,3,4};                                     
    uint8_t data2_in[] = {5,6,7,8};                                     
    uint8_t data3_in[] = {9,10,11,12};                                  
    uint8_t data1_out[4]; 
    uint8_t data2_out[8]; 
    
    size_t  len_in   = sizeof(data1_in);                                 
    size_t  len1_out = sizeof(data1_out);                                
    size_t  len2_out = sizeof(data2_out);                                
    
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data1_in, &len_in);       
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data2_in, &len_in);       
    err_code = nrf_ringbuf_cpy_get(&m_ringbuf, data1_out, &len1_out);    
    	
    err_code = nrf_ringbuf_cpy_put(&m_ringbuf, data3_in, &len_in);       
    err_code = nrf_ringbuf_cpy_get(&m_ringbuf, data2_out, &len2_out);    

    will give you the output

    This can be further confirmed bu examining the implementation of the nrf_ringbuf_cpy_put function in the /components/libraries/nrf_ringbuf.c file. Here, the function calculates available space based in the stored read and write index (rd_idx, wr_idx).

    I would suggest using the queue library instead. If you enable NRF_QUEUE_MODE_OVERFLOW, the queue, if full, will overwrite the oldest element.

    Best regards,

    Heidi

Children
Related