/* ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. This file is part of ChibiOS. ChibiOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * @file chobjfifos.h * @brief Objects FIFO structures and macros. * @details This module implements a generic FIFO queue of objects by * coupling a Guarded Memory Pool (for objects storage) and * a MailBox.
* On the sender side free objects are taken from the pool, filled * and then sent to the receiver, on the receiver side objects are * fetched, used and then returned to the pool. * Operations defined for object FIFOs: * - Take: An object is taken from the pool of the free * objects, can be blocking. * - Return: An object is returned to the pool of the * free objects, it is guaranteed to be non-blocking. * - Send: An object is sent through the mailbox, it is * guaranteed to be non-blocking * - Receive: An object is received from the mailbox, * can be blocking. * . * * @addtogroup objects_fifo * @{ */ #ifndef CHOBJFIFOS_H #define CHOBJFIFOS_H #if (CH_CFG_USE_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__) /*===========================================================================*/ /* Module constants. */ /*===========================================================================*/ /*===========================================================================*/ /* Module pre-compile time settings. */ /*===========================================================================*/ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ #if CH_CFG_USE_MEMPOOLS == FALSE #error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MEMPOOLS" #endif #if CH_CFG_USE_SEMAPHORES == FALSE #error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_SEMAPHORES" #endif #if CH_CFG_USE_MAILBOXES == FALSE #error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MAILBOXES" #endif /*===========================================================================*/ /* Module data structures and types. */ /*===========================================================================*/ /** * @brief Type of an objects FIFO. */ typedef struct ch_objects_fifo { /** * @brief Pool of the free objects. */ guarded_memory_pool_t free; /** * @brief Mailbox of the sent objects. */ mailbox_t mbx; } objects_fifo_t; /*===========================================================================*/ /* Module macros. */ /*===========================================================================*/ /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif /*===========================================================================*/ /* Module inline functions. */ /*===========================================================================*/ /** * @brief Initializes a FIFO object. * @pre The messages size must be a multiple of the alignment * requirement. * * @param[out] ofp pointer to a @p objects_fifo_t structure * @param[in] objsize size of objects * @param[in] objn number of objects available * @param[in] objalign required objects alignment * @param[in] objbuf pointer to the buffer of objects, it must be able * to hold @p objn objects of @p objsize size with * @p objealign alignment * @param[in] msgbuf pointer to the buffer of messages, it must be able * to hold @p objn messages * * @init */ static inline void chFifoObjectInit(objects_fifo_t *ofp, size_t objsize, size_t objn, unsigned objalign, void *objbuf, msg_t *msgbuf) { chGuardedPoolObjectInitAligned(&ofp->free, objsize, objalign); chGuardedPoolLoadArray(&ofp->free, objbuf, objn); chMBObjectInit(&ofp->mbx, msgbuf, objn); } /** * @brief Allocates a free object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @return The pointer to the allocated object. * @retval NULL if an object is not immediately available. * * @iclass */ static inline void *chFifoTakeObjectI(objects_fifo_t *ofp) { return chGuardedPoolAllocI(&ofp->free); } /** * @brief Allocates a free object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The pointer to the allocated object. * @retval NULL if an object is not available within the specified * timeout. * * @sclass */ static inline void *chFifoTakeObjectTimeoutS(objects_fifo_t *ofp, sysinterval_t timeout) { return chGuardedPoolAllocTimeoutS(&ofp->free, timeout); } /** * @brief Allocates a free object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The pointer to the allocated object. * @retval NULL if an object is not available within the specified * timeout. * * @api */ static inline void *chFifoTakeObjectTimeout(objects_fifo_t *ofp, sysinterval_t timeout) { return chGuardedPoolAllocTimeout(&ofp->free, timeout); } /** * @brief Releases a fetched object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objp pointer to the object to be released * * @iclass */ static inline void chFifoReturnObjectI(objects_fifo_t *ofp, void *objp) { chGuardedPoolFreeI(&ofp->free, objp); } /** * @brief Releases a fetched object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objp pointer to the object to be released * * @api */ static inline void chFifoReturnObject(objects_fifo_t *ofp, void *objp) { chGuardedPoolFree(&ofp->free, objp); } /** * @brief Posts an object. * @note By design the object can be always immediately posted. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objp pointer to the object to be posted * * @iclass */ static inline void chFifoSendObjectI(objects_fifo_t *ofp, void *objp) { msg_t msg; msg = chMBPostI(&ofp->mbx, (msg_t)objp); chDbgAssert(msg == MSG_OK, "post failed"); } /** * @brief Posts an object. * @note By design the object can be always immediately posted. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objp pointer to the object to be posted * * @sclass */ static inline void chFifoSendObjectS(objects_fifo_t *ofp, void *objp) { msg_t msg; msg = chMBPostTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); chDbgAssert(msg == MSG_OK, "post failed"); } /** * @brief Posts an object. * @note By design the object can be always immediately posted. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objp pointer to the object to be released * * @api */ static inline void chFifoSendObject(objects_fifo_t *ofp, void *objp) { msg_t msg; msg = chMBPostTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE); chDbgAssert(msg == MSG_OK, "post failed"); } /** * @brief Fetches an object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objpp pointer to the fetched object reference * @return The operation status. * @retval MSG_OK if an object has been correctly fetched. * @retval MSG_TIMEOUT if the FIFO is empty and a message cannot be fetched. * * @iclass */ static inline msg_t chFifoReceiveObjectI(objects_fifo_t *ofp, void **objpp) { return chMBFetchI(&ofp->mbx, (msg_t *)objpp); } /** * @brief Fetches an object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objpp pointer to the fetched object reference * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval MSG_OK if an object has been correctly fetched. * @retval MSG_TIMEOUT if the operation has timed out. * * @sclass */ static inline msg_t chFifoReceiveObjectTimeoutS(objects_fifo_t *ofp, void **objpp, sysinterval_t timeout) { return chMBFetchTimeoutS(&ofp->mbx, (msg_t *)objpp, timeout); } /** * @brief Fetches an object. * * @param[in] ofp pointer to a @p objects_fifo_t structure * @param[in] objpp pointer to the fetched object reference * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval MSG_OK if an object has been correctly fetched. * @retval MSG_TIMEOUT if the operation has timed out. * * @api */ static inline msg_t chFifoReceiveObjectTimeout(objects_fifo_t *ofp, void **objpp, sysinterval_t timeout) { return chMBFetchTimeout(&ofp->mbx, (msg_t *)objpp, timeout); } #endif /* CH_CFG_USE_OBJ_FIFOS == TRUE */ #endif /* CHOBJFIFOS_H */ /** @} */