]> granicus.if.org Git - esp-idf/commitdiff
freertos/ringbuf: Add an API xRingbufferIsNextItemWrapped()
authorPiyush Shah <piyush@espressif.com>
Mon, 20 Nov 2017 14:52:20 +0000 (20:22 +0530)
committerPiyush Shah <piyush@espressif.com>
Thu, 7 Dec 2017 11:34:18 +0000 (17:04 +0530)
Useful to check if the next item to receive is wrapped or not.
This is valid only if the ring buffer is initialised with type
RINGBUF_TYPE_ALLOWSPLIT.

This is as per the feature request here:
https://github.com/espressif/esp-idf/issues/806

Signed-off-by: Piyush Shah <piyush@espressif.com>
components/freertos/include/freertos/ringbuf.h
components/freertos/ringbuf.c

index f0cf82fca538bcd110bf9fdbfb3a9e83e528f130..259ce0f16bc3c4e3975b663c67ffedbee47eb5e1 100644 (file)
@@ -110,6 +110,23 @@ size_t xRingbufferGetMaxItemSize(RingbufHandle_t ringbuf);
  */
 size_t xRingbufferGetCurFreeSize(RingbufHandle_t ringbuf);
 
+/**
+ * @brief Check if the next item is wrapped
+ *
+ * This API tells if the next item that is available for a Receive is wrapped
+ * or not. This is valid only if the ring buffer type is RINGBUF_TYPE_ALLOWSPLIT
+ *
+ * @note This API is not thread safe. So, if multiple threads are accessing the same
+ * ring buffer, it is the application's responsibility to ensure atomic access to this
+ * API and the subsequent Receive
+ *
+ * @param ringbuf - Ring buffer to query
+ *
+ * @return true if the next item is wrapped around
+ * @return false if the next item is not wrapped
+ */
+bool xRingbufferIsNextItemWrapped(RingbufHandle_t ringbuf);
+
 /**
  * @brief  Insert an item into the ring buffer
  *
index f79bf3ed9693abae444f9952ece818b9d23171a4..7ae1723fb92e23394527fbc3fda01c01ecc29a41 100644 (file)
@@ -32,6 +32,7 @@ typedef enum {
 typedef enum {
     iflag_free = 1,             //Buffer is not read and given back by application, free to overwrite
     iflag_dummydata = 2,        //Data from here to end of ringbuffer is dummy. Restart reading at start of ringbuffer.
+    iflag_wrap = 4,             //Valid for RINGBUF_TYPE_ALLOWSPLIT, indicating that rest of the data is wrapped around
 } itemflag_t;
 
 
@@ -203,6 +204,9 @@ static BaseType_t copyItemToRingbufAllowSplit(ringbuf_t *rb, uint8_t *buffer, si
             if (buffer_size == 0) {
                 rb->write_ptr=rb->data;
                 return pdTRUE;
+            } else {
+                /* Indicate the wrapping */
+                hdr->flags|=iflag_wrap;
             }
         } else {
             //Huh, only the header fit. Mark as dummy so the receive function doesn't receive
@@ -359,6 +363,7 @@ static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) {
     configASSERT((hdr->flags & iflag_dummydata)==0);
     configASSERT((hdr->flags & iflag_free)==0);
     //Mark the buffer as free.
+    hdr->flags&=~iflag_wrap;
     hdr->flags|=iflag_free;
 
     //Do a cleanup pass.
@@ -553,6 +558,15 @@ size_t xRingbufferGetMaxItemSize(RingbufHandle_t ringbuf)
     return rb->maxItemSize;
 }
 
+bool xRingbufferIsNextItemWrapped(RingbufHandle_t ringbuf)
+{
+    ringbuf_t *rb=(ringbuf_t *)ringbuf;
+    configASSERT(rb);
+    buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->read_ptr;
+    return hdr->flags & iflag_wrap;
+}
+
+
 BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t dataSize, TickType_t ticks_to_wait)
 {
     ringbuf_t *rb=(ringbuf_t *)ringbuf;