From: Piyush Shah Date: Mon, 20 Nov 2017 14:52:20 +0000 (+0530) Subject: freertos/ringbuf: Add an API xRingbufferIsNextItemWrapped() X-Git-Tag: v3.1-beta1~532^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c199b0de65df8f58e79e19ef6e40945f2eefe81;p=esp-idf freertos/ringbuf: Add an API xRingbufferIsNextItemWrapped() 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 --- diff --git a/components/freertos/include/freertos/ringbuf.h b/components/freertos/include/freertos/ringbuf.h index f0cf82fca5..259ce0f16b 100644 --- a/components/freertos/include/freertos/ringbuf.h +++ b/components/freertos/include/freertos/ringbuf.h @@ -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 * diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index f79bf3ed96..7ae1723fb9 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -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;