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

nrf_ringbuf_alloc , nrf_ringbuf_put overwrite issue

Hello, 

I am running such code deliberately, it is allocating the buffer flawlessly until the 10th run (102*10 = 1020). After that, it gives 4 from the allocation function.

and as I am still filling 102 bytes by nrf_ringbuf_put function it is overflowing but not gives any error, yet it is starting to allocate 102 bytes after the 12nd cycle until the 21st cycle. 

My expectation is it should run till the 10th cycle, then it should give memory full error continuously.

NRF_RINGBUF_DEF(testRingbuf,1024);
void testfunc(){
    nrf_ringbuf_init(&testRingbuf);
    len =102;
    for(int i=0;i<20;i++){
        nrf_ringbuf_alloc(&testRingbuf,&bufferAllocChunk,&len, true);
        fillbuffer(bufferAllocChunk,len);
        err_code = nrf_ringbuf_put(&ppgRingbuf, PPG_WATERMARK_BUFFER_SIZE);
    }
}

One more detail ;

If I allocate and put bytes amount of two's power (ex:128,256,...) it works as intended(it gives "no-mem" error until freeing some space)

But if I allocate /put a number of bytes such as 102 or any other number other than two's power, the library gives a "no-mem" error once and it is overwriting. I don't know if we are able to allocate/put an arbitrary number of bytes or we need to put/allocate only two's power.

Parents
  • Hi,

    It should work for putting any amount of data into the ring buffer, not only power-of-two length amounts of data. However, when the data is a power of two you will always align to the "wraparound" point of the ring buffer, and the amount that you try to allocate will always either fit entirely or no bytes will fit at all.

    For the code example that you provided, you do not check the error value returned from nrf_ringbuf_alloc(), and the call to nrf_ringbuf_put() is to a different buffer than the one you allocate to.

    Note that len, on iteration 11 (when only 4 bytes are available in the ring buffer) will get set to 4 (the actual amount of bytes available in the buffer), and so for consequent iterations 4 bytes will be attempted allocated in each instance and not 102 bytes. (The p_length argument of nrf_ringbuf_alloc() is both in and out.)

    The call to nrf_ringbuf_put() should use the value pointed to by p_length after the call to nrf_ringbuf_alloc() for its length argument (or a smaller value). In your example code you use PPG_WATERMARK_BUFFER_SIZE, which I assume is larger than 4.

    Regards,
    Terje

  • Hi ,

    I have modified the code like this ;

        len = PPG_WATERMARK_BUFFER_SIZE;
        err_code = nrf_ringbuf_alloc(&ppgRingbuf,&ppgBufferAllocChunk,&len,true);
        if((len== PPG_WATERMARK_BUFFER_SIZE)&(err_code == NRF_SUCCESS) ){
          printf("Allocated len:%d - nrf_ringbuf_alloc Return:%d\r\n",len,err_code);
          err_code = nrf_ringbuf_put(&ppgRingbuf,PPG_WATERMARK_BUFFER_SIZE-10);
        }else{
          printf("Allocated len:%d - nrf_ringbuf_alloc ReturN:%d\r\n",len,err_code);
        }

    Now my problem is how to de-allocate the currently allocated buffer. Because it is less than i need,  so I want to check it on the next iteration and I will fill it whenever it gives my requested amount of length.

    my current work-around is like this;

        len = PPG_WATERMARK_BUFFER_SIZE;
        err_code = nrf_ringbuf_alloc(&ppgRingbuf,&ppgBufferAllocChunk,&len,true);
        if((len== PPG_WATERMARK_BUFFER_SIZE)&(err_code == NRF_SUCCESS) ){
          printf("Allocated len:%d - nrf_ringbuf_alloc Return:%d\r\n",len,err_code);
          MAX30102_ReadFIFO(ppgBufferAllocChunk,PPG_WATERMARK_BUFFER_SIZE);
        }else{
          printf("Allocated len:%d - nrf_ringbuf_alloc ReturN:%d\r\n",len,err_code);
          len = 0;
        }
        err_code = nrf_ringbuf_put(&ppgRingbuf,len);

    I call err_code = nrf_ringbuf_put(&ppgRingbuf,len); function with the zero-length to de-allocate current allocation.I don't know the drawbacks of this, but it works as I expected.

  • Hi,

    Using nrf_ringbuf_put() with length 0 should work, yes. It will reset the ring buffer to the state where nothing was allocated.

    Please note that if you want to fill anything into the ring buffer then you should do that between nrf_ringbuf_alloc() and nrf_ringbuf_put(), as you did in the example code in the opening post. The first code example in your latest post does not fill anything in the buffer even though it tells the buffer that it has filled "PPG_WATERMARK_BUFFER_SIZE-10" bytes with the call to nrf_ringbuf_put().

    Regards,
    Terje

Reply
  • Hi,

    Using nrf_ringbuf_put() with length 0 should work, yes. It will reset the ring buffer to the state where nothing was allocated.

    Please note that if you want to fill anything into the ring buffer then you should do that between nrf_ringbuf_alloc() and nrf_ringbuf_put(), as you did in the example code in the opening post. The first code example in your latest post does not fill anything in the buffer even though it tells the buffer that it has filled "PPG_WATERMARK_BUFFER_SIZE-10" bytes with the call to nrf_ringbuf_put().

    Regards,
    Terje

Children
No Data
Related