Multi purpose buffer module.
Multipurpose ringbuffer
Since there weren't any ringbuffers available on the internet optimized for 32-Bit ARM operation without unix-calls and dynamic memory... I created one.
This module is a fixed ringbuffer, it does not allocate any memory, it can work as FIFO or LIFO or any other exotic mode depending on your imagination. With a fixed 32Bit element size it is optimized for 32 bit arm processors. Any smaller value will have overhead, any larger value will require a double entry. (not recommended)
I hope you can use it.
Information
This is not a C++ class, it is a C Module. It does work object oriented, however you cannot work on the object, you work with the object.
Import programxIFO_example
Small example for xIFO
xIFO.c
- Committer:
- jeroen3
- Date:
- 2013-10-28
- Revision:
- 0:a04dc0c57d20
- Child:
- 1:5f59aa9b86ed
File content as of revision 0:a04dc0c57d20:
/** * @file xifo.c * @brief xifo circular buffer * @details xifo supplies object oriented circular buffer with 32 bit size elements. \n * To use either as FIFO (First In First Out) or as FILO (First In Last Out) * * @Author Jeroen Lodder * @Date April 2013 * @version 2 * * @{ */ #include "xifo.h" /** * @brief Initialise buffer object structure. * * @note Does not clear memory pool. * * @param[in] c Pointer to @p xifo_t object used for configuration. * @param[in] s Number of elements buffer can hold (size). * @param[in] sp Start of pre-allocated memory pool. */ void xifo_init(xifo_t *c, uint32_t s, uint32_t *sp){ c->startpool = sp; c->endpool = &sp[s-1]; c->size = s; c->full = 0; c->elementcount = 0; c->read = sp; c->write = sp; } /** * @brief Clear buffer contents * * @note Must be used on initialised buffer object. * * @param[in] c Pointer to @p xifo_t object. */ void xifo_clear(xifo_t *c){ c->ptemp = c->startpool; while(c->ptemp <= c->endpool){ *c->ptemp++ = 0; } } /** * @brief Read from buffer (lr) Least Recent oriented (fifo) * * @note Buffer state will be preserved * * @warning Consider this opertaion as atomic! * * @details Read n elements from the oldest element to the most recent. * As for index[0] the least recently added element is returned. * And for index[elementcount] the most recent element is returned. * This makes it possible to peek in fifo. * * @param[in] c Pointer to @p xifo_t used for configuration. * @param[in] index Index relative from least recent * * @return Contents of element or 0 if failed (element can hold 0) */ uint32_t xifo_read_lr(xifo_t *c, uint32_t index){ /* Verify there is valid data to read */ if(index+1 > c->elementcount){ return 0; /* Nothing to read there */ } /* Calculate index of oldest element */ index = (c->elementcount-1) - index; /* Set pointer */ c->ptemp = (c->read) - index; if(c->ptemp < c->startpool){ /* We exceeded pool boundaries */ /* Calculate overshoot (startpool - indexptr) and subtract from end */ /* Since one element of overshoot results in end - 1 you would miss the last value */ c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp); } /* Read most recent */ return *c->ptemp; } /** * @brief Read from buffer (mr) Most Recent oriented (filo) * * @note Buffer state will be preserved * * @warning Consider this opertaion as atomic! * * @details Read n elements back in time. * As for index[0] the most recently added element is returned. * And for index[elementcount] the oldest element is returned. * This makes it possible to keep history. For DSP application. * * @param[in] c Pointer to @p xifo_t used for configuration. * @param[in] index Index relative from most recent * * @return Contents of element or 0 if failed (element can hold 0) */ uint32_t xifo_read_mr(xifo_t *c, uint32_t index){ /* Verify there is valid data to read */ if(index+1 > c->elementcount){ return 0; /* Nothing to read there */ } /* Set pointer */ c->ptemp = (c->read) - index; /* Validate pointer */ if(c->ptemp < c->startpool){ /* We exceeded pool boundaries */ /* Calculate overshoot (startpool - indexptr) and subtract from end */ /* Since one element of overshoot results in end - 1 you would miss the last value */ c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp); } /* Read most recent */ return *c->ptemp; } /** * @brief Pop (mr) most recent from buffer (filo) * * @note Buffer state will be altered * * @warning Consider this opertaion as atomic! * * @details Read and remove the most recently added from the buffer. * Using this results in a stack type of buffer. * * @param[in] c Pointer to @p xifo_t used for configuration. * * @return Contents of element or 0 if failed (element can hold 0) */ uint32_t xifo_pop_mr(xifo_t *c){ /* Verify there is valid data read */ if(c->elementcount == 0){ return 0; /* Nothing to read there */ } /* Read */ c->temp = *c->read; /* Empty */ *c->read = 0; /* Most recent element read, return write pointer */ c->write = c->read; /* Decrement read pointer */ c->read--; /* Validate pointer */ if( c->read < c->startpool ){ /* We exceeded pool boundaries */ c->read = c->endpool; } /* Reduce elementcount */ c->elementcount--; if(c->elementcount < c->size) c->full = 0; return c->temp; } /** * @brief Pop (lr) least recent from buffer (fifo) * * @note Buffer state will be altered * * @warning Consider this opertaion as atomic! * * @details Read and remove the least recently added from the buffer. * Using this results in a fifo type of buffer. * * @param[in] c Pointer to @p xifo_t used for configuration. * * @return Contents of element or 0 if failed (element can hold 0) */ uint32_t xifo_pop_lr(xifo_t *c){ /* Verify there is valid data read */ if(c->elementcount == 0){ return 0; /* Nothing to read there */ } /* Derive least recent buffer element */ c->ptemp = c->read+1 - c->elementcount; /* Validate pointer */ if(c->ptemp < c->startpool){ /* We exceeded pool boundaries */ /* Calculate overshoot (startpool - indexptr) and subtract from end */ /* Since one element of overshoot results in end - 1 you would miss the last value */ c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp); } /* Read oldest buffer element */ { /* block with temporary variable to prevent stack use */ register uint32_t element; /* Read to temp register */ element = *c->ptemp; /* Empty */ *c->ptemp = 0; /* Clear temp register */ c->temp = element; } /* Reduce elementcount */ c->elementcount--; /* Check full flag */ if(c->elementcount < c->size) c->full = 0; return c->temp; } /** * @brief Write to buffer * * @note Readpointer is automatically set to the last added element. * * @warning Consider this opertaion as atomic! * * @details Adds a value to the buffer. * Automatically overwrites oldest elements when full. * * @param[in] c Pointer to @p xifo_t used for configuration. * @param[in] data Data to add to buffer * * @return Number of free buffer elements */ uint32_t xifo_write(xifo_t *c, uint32_t data){ /* Write data */ *c->write = data; /* Update read pointer to most recent element */ c->read = c->write; /* Write pointer increment */ c->write += 1; /* Validate pointer */ if( c->write > c->endpool){ /* We exceeded pool boundaries */ c->write = c->startpool; } /* Update elementcount */ c->elementcount++; /* Verify full */ if( c->elementcount >= c->size ){ c->full = 1; c->elementcount = c->size; } /* return free elements count */ return c->size - c->elementcount; } /** * @brief Get buffer size * * @param[in] c Pointer to @p xifo_t used for configuration. * * @return Size of memory pool in elements */ uint32_t xifo_get_size(xifo_t *c){ return c->size; } /** * @brief Get number of used elements * * @param[in] c Pointer to @p xifo_t used for configuration. * * @return Number of used buffer elements */ uint32_t xifo_get_used(xifo_t *c){ return c->elementcount; } /** * @brief Get number of free elements * * @param[in] c Pointer to @p xifo_t used for configuration. * * @return Number of free elements */ uint32_t xifo_get_free(xifo_t *c){ return c->size - c->elementcount; } /** * @brief Get full flag * * @param[in] c Pointer to @p xifo_t used for configuration. * * @return 1 if full */ uint32_t xifo_get_full(xifo_t *c){ return c->full; } /** @} */