From 1283a5068d4a4bee3f965915ca21528c56d28def Mon Sep 17 00:00:00 2001 From: TexZK Date: Sat, 4 Jul 2015 17:29:41 +0200 Subject: Added TriBuf files and demo [WIP] --- os/various/tribuf.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++ os/various/tribuf.h | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 436 insertions(+) create mode 100644 os/various/tribuf.c create mode 100644 os/various/tribuf.h (limited to 'os') diff --git a/os/various/tribuf.c b/os/various/tribuf.c new file mode 100644 index 0000000..cc3987a --- /dev/null +++ b/os/various/tribuf.c @@ -0,0 +1,211 @@ +/* + Copyright (C) 2014..2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "osal.h" +#include "tribuf.h" + +/** + * @file tribuf.c + * @brief Triple buffer handler source. + * + * @addtogroup TriBuf + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the tribuf handler object. + * + * @param[in] handler Pointer to the tribuf handler object. + * @param[in] front Pointer to the initial front buffer. + * @param[in] back Pointer to the initial back buffer. + * @param[in] orphan Pointer to the initial orphan buffer. + * + * @init + */ +void tribufObjectInit(tribuf_t *handler, void *front, void *back, void *orphan) { + + handler->front = front; + handler->back = back; + handler->orphan = orphan; +#if (TRIBUF_USE_WAIT == TRUE) + chSemObjectInit(&handler->ready, 0); +#else + handler->ready = false; +#endif +} + +/** + * @brief Gets the current front buffer. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Pointer to the current front buffer. + * + * @api + */ +void *tribufGetFront(tribuf_t *handler) { + + void *front; + + osalSysLock(); + front = tribufGetFrontI(handler); + osalSysUnlock(); + return front; +} + +/** + * @brief Swaps the current front buffer. + * + * @details Exchanges the pointer of the current front buffer, which will be + * dismissed, with the pointer of the current orphan buffer, which + * holds the content of the new front buffer. + * + * @pre The orphan buffer holds new data, swapped by the back buffer. + * @pre The fron buffer is ready for swap. + * @post The orphan buffer can be used as new back buffer in the future. + * + * @param[in] handler Pointer to the tribuf handler object. + * + * @iclass + */ +void tribufSwapFrontI(tribuf_t *handler) { + + void *front; + + osalDbgCheckClassI(); + + front = handler->orphan; + handler->orphan = handler->front; + handler->front = front; +} + +/** + * @brief Swaps the current front buffer. + * + * @details Exchanges the pointer of the current front buffer, which will be + * dismissed, with the pointer of the current orphan buffer, which + * holds the content of the new front buffer. + * + * @pre The orphan buffer holds new data, swapped by the back buffer. + * @pre The fron buffer is ready for swap. + * @post The orphan buffer can be used as new back buffer in the future. + * + * @param[in] handler Pointer to the tribuf handler object. + * + * @api + */ +void tribufSwapFront(tribuf_t *handler) { + + osalSysLock(); + tribufSwapFrontI(handler); + osalSysUnlock(); +} + +/** + * @brief Gets the current back buffer. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Pointer to the current back buffer. + * + * @api + */ +void *tribufGetBack(tribuf_t *handler) { + + void *back; + + osalSysLock(); + back = tribufGetBackI(handler); + osalSysUnlock(); + return back; +} + +/** + * @brief Swaps the current back buffer. + * + * @details Exchanges the pointer of the current back buffer, which holds new + * useful data, with the pointer of the current orphan buffer. + * + * @pre The orphan buffer holds no meaningful data. + * @post The orphan buffer is candidate for new front buffer. + * @post A new front buffer is ready and signaled. + * + * @param[in] handler Pointer to the tribuf handler object. + * + * @iclass + */ +void tribufSwapBackI(tribuf_t *handler) { + + void *back; + + osalDbgCheckClassI(); + + back = handler->orphan; + handler->orphan = handler->back; + handler->back = back; + +#if (TRIBUF_USE_WAIT == TRUE) + if (0 == chSemGetCounterI(&handler->ready)) + chSemSignalI(&handler->ready); +#else + handler->ready = true; +#endif +} + +/** + * @brief Swaps the current back buffer. + * + * @details Exchanges the pointer of the current back buffer, which holds new + * useful data, with the pointer of the current orphan buffer. + * + * @pre The orphan buffer holds no meaningful data. + * @post The orphan buffer is candidate for new front buffer. + * @post A new front buffer is ready and signaled. + * + * @param[in] handler Pointer to the tribuf handler object. + * + * @api + */ +void tribufSwapBack(tribuf_t *handler) { + + osalSysLock(); + tribufSwapBackI(handler); + osalSysUnlock(); +} + +/** @} */ diff --git a/os/various/tribuf.h b/os/various/tribuf.h new file mode 100644 index 0000000..28fffb2 --- /dev/null +++ b/os/various/tribuf.h @@ -0,0 +1,225 @@ +/* + Copyright (C) 2014..2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file tribuf.h + * @brief Triple buffer handler header. + * + * @addtogroup TriBuf + * @{ + */ + +#ifndef _TRIBUF_H_ +#define _TRIBUF_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Triple buffer configuration options + * @{ + */ + +#if !defined(TRIBUF_USE_WAIT) || defined(__DOXYGEN__) +/** + * @brief Triple buffers use blocking functions. + */ +#define TRIBUF_USE_WAIT TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Triple buffer handler object. + */ +typedef struct { + void *front; /**< @brief Current front buffer pointer.*/ + void *back; /**< @brief Current back buffer pointer.*/ + void *orphan; /**< @brief Current orphan buffer pointer.*/ +#if (TRIBUF_USE_WAIT == TRUE) + semaphore_t ready; /**< @brief A new front buffer is ready.*/ +#else + bool ready; /**< @brief A new front buffer is ready.*/ +#endif +} tribuf_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Checks if a new front buffer is ready. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Availability of a new front buffer. + * + * @iclass + */ +static inline +bool tribufIsReadyI(tribuf_t *handler) +{ + osalDbgCheckClassI(); + +#if (TRIBUF_USE_WAIT == TRUE) + return (0 != chSemGetCounterI(&handler->ready)); +#else + return handler->ready; +#endif +} + +#if (TRIBUF_USE_WAIT == TRUE) || defined(__DOXYGEN__) + +/** + * @brief Waits until a new front buffer is ready, with timeout. + * + * @post The ready signal, result of the back buffer swap, is consumed. + * + * @param[in] handler Pointer to the tribuf handler object. + * @param[in] timeout Timeout of the wait operation. + * @return Timeout error code, as from @p chSemWaitTimeoutS. + * + * @see chSemWaitTimeoutS + * @sclass + */ +static inline +msg_t tribufWaitReadyTimeoutS(tribuf_t *handler, systime_t timeout) +{ + osalDbgCheckClassS(); + + return chSemWaitTimeoutS(&handler->ready, timeout); +} + +/** + * @brief Waits until a new front buffer is ready, with timeout. + * + * @post The ready signal, result of the back buffer swap, is consumed. + * + * @param[in] handler Pointer to the tribuf handler object. + * @param[in] timeout Timeout of the wait operation. + * @return Timeout error code, as from @p chSemWaitTimeout. + * + * @see chSemWaitTimeout + * @api + */ +static inline +msg_t tribufWaitReadyTimeout(tribuf_t *handler, systime_t timeout) +{ + return chSemWaitTimeout(&handler->ready, timeout); +} + +/** + * @brief Waits until a new front buffer is ready. + * + * @post The ready signal, result of the back buffer swap, is consumed. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Timeout error code, as from @p chSemWaitS. + * + * @see chSemWaitS + * @sclass + */ +static inline +void tribufWaitReadyS(tribuf_t *handler) +{ + osalDbgCheckClassS(); + + chSemWaitS(&handler->ready); +} + +/** + * @brief Waits until a new front buffer is ready. + * + * @post The ready signal, result of the back buffer swap, is consumed. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Timeout error code, as from @p chSemWait. + * + * @see chSemWait + * @api + */ +static inline +void tribufWaitReady(tribuf_t *handler) +{ + chSemWait(&handler->ready); +} + +#endif /* (TRIBUF_USE_WAIT == TRUE) || defined(__DOXYGEN__) */ + +/** + * @brief Gets the current front buffer. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Pointer to the current front buffer. + * + * @iclass + */ +static inline +void *tribufGetFrontI(tribuf_t *handler) { + + osalDbgCheckClassI(); + + return handler->front; +} + +/** + * @brief Gets the current back buffer. + * + * @param[in] handler Pointer to the tribuf handler object. + * @return Pointer to the current back buffer. + * + * @iclass + */ +static inline +void *tribufGetBackI(tribuf_t *handler) { + + osalDbgCheckClassI(); + + return handler->back; +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void tribufObjectInit(tribuf_t *handler, void *front, void *back, void *orphan); + void *tribufGetFront(tribuf_t *handler); + void tribufSwapFrontI(tribuf_t *handler); + void tribufSwapFront(tribuf_t *handler); + void *tribufGetBack(tribuf_t *handler); + void tribufSwapBackI(tribuf_t *handler); + void tribufSwapBack(tribuf_t *handler); +#ifdef __cplusplus +} +#endif + +#endif /* _TRIBUF_H_ */ +/** @} */ -- cgit v1.2.3