Hi, I have a BLE device in Observer role - it will constantly scan for Broadcasters broadcasting our unique UUID and put these scanned devices into a Ring Buffer.
The reason I thought of using a Ring Buffer is because newly scanned devices should replace old ones - which seemed appropriate because a Ring Buffer automatically does wrapping: so let's say I make it large enough to hold 10 scanned devices --- when the 11th device is found, it should replace the 1st device (because it is "obsolete") in the Ring Buffer.
I went through the documentation and thought of using the "claim" API which said that it did not support that kind of wrapping:
This boundary is invisible to the user using the normal put/get APIs, but becomes a barrier to the “claim” API, because obviously no contiguous region can be returned that crosses the end of the buffer. This can be surprising to application code, and produce performance artifacts when transfers need to happen close to the end of the buffer, as the number of calls to claim/finish needs to double for such transfers.
So I decided to try the normal put/get APIs as mentioned, but the ring_buf_put function does not cause a wrap around with some test code:
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/ring_buffer.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
#define RING_BUFF_SIZE 10
RING_BUF_DECLARE(my_ring_buf, RING_BUFF_SIZE);
int main(void)
{
int nbytes = 0;
int tbytes = 0;
nbytes = ring_buf_put(&my_ring_buf, "Hello", 5);
tbytes += nbytes;
LOG_INF("%d bytes written to RB (%d total so far).", nbytes, tbytes);
nbytes = ring_buf_put(&my_ring_buf, "World", 5);
tbytes += nbytes;
LOG_INF("%d bytes written to RB (%d total so far).", nbytes, tbytes);
nbytes = ring_buf_put(&my_ring_buf, "FooBar", 6);
tbytes += nbytes;
LOG_INF("%d bytes written to RB (%d total so far).", nbytes, tbytes);
nbytes = ring_buf_put(&my_ring_buf, "FooBar", 6);
tbytes += nbytes;
LOG_INF("%d bytes written to RB (%d total so far).", nbytes, tbytes);
return 0;
}
Output:
SEGGER J-Link V7.96e - Real time terminal output
SEGGER J-Link V12.0, SN=822000525
Process: JLinkExe
*** Booting nRF Connect SDK v3.5.99-ncs1 ***
[00:00:00.417,175] <inf> main: 5 bytes written to RB (5 total so far).
[00:00:00.417,175] <inf> main: 5 bytes written to RB (10 total so far).
[00:00:00.417,175] <inf> main: 0 bytes written to RB (10 total so far).
[00:00:00.417,205] <inf> main: 0 bytes written to RB (10 total so far).
[00:00:00.417,236] <inf> main: Ring Buffer:
48 65 6c 6c 6f 57 6f 72 6c 64 00 00 00 00 00 00 |HelloWor ld.......
Here the RB is 10 bytes large and accepts the first 5 + 5 bytes ("Hello" + "World"), but then I also want to insert "FooBar" and make it wrap around to the first byte so that "HelloWorld" becomes "FooBarorld". But that does not seem to work. Is this possible to do? if not, would you recommend some other data structure that would work better for this situation? Thanks.