/* ChibiOS - Copyright (C) 2006..2016 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 chmboxes.c * @brief Mailboxes code. * * @addtogroup mailboxes * @details Asynchronous messages. *

Operation mode

* A mailbox is an asynchronous communication mechanism.
* Operations defined for mailboxes: * - Post: Posts a message on the mailbox in FIFO order. * - Post Ahead: Posts a message on the mailbox with urgent * priority. * - Fetch: A message is fetched from the mailbox and removed * from the queue. * - Reset: The mailbox is emptied and all the stored messages * are lost. * . * A message is a variable of type msg_t that is guaranteed to have * the same size of and be compatible with (data) pointers (anyway an * explicit cast is needed). * If larger messages need to be exchanged then a pointer to a * structure can be posted in the mailbox but the posting side has * no predefined way to know when the message has been processed. A * possible approach is to allocate memory (from a memory pool for * example) from the posting side and free it on the fetching side. * Another approach is to set a "done" flag into the structure pointed * by the message. * @pre In order to use the mailboxes APIs the @p CH_CFG_USE_MAILBOXES * option must be enabled in @p chconf.h. * @note Compatible with RT and NIL. * @{ */ #include "ch.h" #if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__) /*===========================================================================*/ /* Module exported variables. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local variables. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local functions. */ /*===========================================================================*/ /*===========================================================================*/ /* Module exported functions. */ /*===========================================================================*/ /** * @brief Initializes a @p mailbox_t object. * * @param[out] mbp the pointer to the @p mailbox_t structure to be * initialized * @param[in] buf pointer to the messages buffer as an array of @p msg_t * @param[in] n number of elements in the buffer array * * @init */ void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n) { chDbgCheck((mbp != NULL) && (buf != NULL) && (n > (size_t)0)); mbp->buffer = buf; mbp->rdptr = buf; mbp->wrptr = buf; mbp->top = &buf[n]; mbp->cnt = (size_t)0; mbp->reset = false; chThdQueueObjectInit(&mbp->qw); chThdQueueObjectInit(&mbp->qr); } /** * @brief Resets a @p mailbox_t object. * @details All the waiting threads are resumed with status @p MSG_RESET and * the queued messages are lost. * @post The mailbox is in reset state, all operations will fail and * return @p MSG reset until the mailbox is enabled again using * @p chMBResumeX(). * * @param[in] mbp the pointer to an initialized @p mailbox_t object * * @api */ void chMBReset(mailbox_t *mbp) { chSysLock(); chMBResetI(mbp); chSchRescheduleS(); chSysUnlock(); } /** * @brief Resets a @p mailbox_t object. * @details All the waiting threads are resumed with status @p MSG_RESET and * the queued messages are lost. * @post The mailbox is in reset state, all operations will fail and * return @p MSG reset until the mailbox is enabled again using * @p chMBResumeX(). * * @param[in] mbp the pointer to an initialized @p mailbox_t object * * @api */ void chMBResetI(mailbox_t *mbp) { chDbgCheckClassI(); chDbgCheck(mbp != NULL); mbp->wrptr = mbp->buffer; mbp->rdptr = mbp->buffer; mbp->cnt = (size_t)0; mbp->reset = true; chThdDequeueAllI(&mbp->qw, MSG_RESET); chThdDequeueAllI(&mbp->qr, MSG_RESET); } /** * @brief Posts a message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @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 a message has been correctly posted. * @retval MSG_RESET if the mailbox has been reset. * @retval MSG_TIMEOUT if the operation has timed out. * * @api */ msg_t chMBPostTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) { msg_t rdymsg; chSysLock(); rdymsg = chMBPostTimeoutS(mbp, msg, timeout); chSysUnlock(); return rdymsg; } /** * @brief Posts a message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @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 a message has been correctly posted. * @retval MSG_RESET if the mailbox has been reset. * @retval MSG_TIMEOUT if the operation has timed out. * * @sclass */ msg_t chMBPostTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) { msg_t rdymsg; chDbgCheckClassS(); chDbgCheck(mbp != NULL); do { /* If the mailbox is in reset state then returns immediately.*/ if (mbp->reset) { return MSG_RESET; } /* Is there a free message slot in queue? if so then post.*/ if (chMBGetFreeCountI(mbp) > (size_t)0) { *mbp->wrptr++ = msg; if (mbp->wrptr >= mbp->top) { mbp->wrptr = mbp->buffer; } mbp->cnt++; /* If there is a reader waiting then makes it ready.*/ chThdDequeueNextI(&mbp->qr, MSG_OK); chSchRescheduleS(); return MSG_OK; } /* No space in the queue, waiting for a slot to become available.*/ rdymsg = chThdEnqueueTimeoutS(&mbp->qw, timeout); } while (rdymsg == MSG_OK); return rdymsg; } /** * @brief Posts a message into a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is full. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @return The operation status. * @retval MSG_OK if a message has been correctly posted. * @retval MSG_RESET if the mailbox has been reset. * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be * posted. * * @iclass */ msg_t chMBPostI(mailbox_t *mbp, msg_t msg) { chDbgCheckClassI(); chDbgCheck(mbp != NULL); /* If the mailbox is in reset state then returns immediately.*/ if (mbp->reset) { return MSG_RESET; } /* Is there a free message slot in queue? if so then post.*/ if (chMBGetFreeCountI(mbp) > (size_t)0) { *mbp->wrptr++ = msg; if (mbp->wrptr >= mbp->top) { mbp->wrptr = mbp->buffer; } mbp->cnt++; /* If there is a reader waiting then makes it ready.*/ chThdDequeueNextI(&mbp->qr, MSG_OK); return MSG_OK; } /* No space, immediate timeout.*/ return MSG_TIMEOUT; } /** * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @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 a message has been correctly posted. * @retval MSG_RESET if the mailbox has been reset. * @retval MSG_TIMEOUT if the operation has timed out. * * @api */ msg_t chMBPostAheadTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) { msg_t rdymsg; chSysLock(); rdymsg = chMBPostAheadTimeoutS(mbp, msg, timeout); chSysUnlock(); return rdymsg; } /** * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @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 a message has been correctly posted. * @retval MSG_RESET if the mailbox has been reset. * @retval MSG_TIMEOUT if the operation has timed out. * * @sclass */ msg_t chMBPostAheadTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) { msg_t rdymsg; chDbgCheckClassS(); chDbgCheck(mbp != NULL); do { /* If the mailbox is in reset state then returns immediately.*/ if (mbp->reset) { return MSG_RESET; } /* Is there a free message slot in queue? if so then post.*/ if (chMBGetFreeCountI(mbp) > (size_t)0) { if (--mbp->rdptr < mbp->buffer) { mbp->rdptr = mbp->top - 1; } *mbp->rdptr = msg; mbp->cnt++; /* If there is a reader waiting then makes it ready.*/ chThdDequeueNextI(&mbp->qr, MSG_OK); chSchRescheduleS(); return MSG_OK; } /* No space in the queue, waiting for a slot to become available.*/ rdymsg = chThdEnqueueTimeoutS(&mbp->qw, timeout); } while (rdymsg == MSG_OK); return rdymsg; } /** * @brief Posts an high priority message into a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is full. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @return The operation status. * @retval MSG_OK if a message has been correctly posted. * @retval MSG_RESET if the mailbox has been reset. * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be * posted. * * @iclass */ msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) { chDbgCheckClassI(); chDbgCheck(mbp != NULL); /* If the mailbox is in reset state then returns immediately.*/ if (mbp->reset) { return MSG_RESET; } /* Is there a free message slot in queue? if so then post.*/ if (chMBGetFreeCountI(mbp) > (size_t)0) { if (--mbp->rdptr < mbp->buffer) { mbp->rdptr = mbp->top - 1; } *mbp->rdptr = msg; mbp->cnt++; /* If there is a reader waiting then makes it ready.*/ chThdDequeueNextI(&mbp->qr, MSG_OK); return MSG_OK; } /* No space, immediate timeout.*/ return MSG_TIMEOUT; } /** * @brief Retrieves a message from a mailbox. * @details The invoking thread waits until a message is posted in the mailbox * or the specified time runs out. * * @param[in] mbp the pointe
/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
                 2011 Giovanni Di Sirio.

    This file is part of ChibiOS/RT.

    ChibiOS/RT 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/RT 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 <http://www.gnu.org/licenses/>.
*/

/**
 * @file    templates/halconf.h
 * @brief   HAL configuration header.
 * @details HAL configuration file, this file allows to enable or disable the
 *          various device drivers from your application. You may also use
 *          this file in order to override the device drivers default settings.
 *
 * @addtogroup HAL_CONF
 * @{
 */

#ifndef _HALCONF_H_
#define _HALCONF_H_

#include "mcuconf.h"

/**
 * @brief   Enables the PAL subsystem.
 */
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL                 TRUE
#endif

/**
 * @brief   Enables the ADC subsystem.
 */
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC                 FALSE
#endif

/**
 * @brief   Enables the CAN subsystem.
 */
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN                 FALSE
#endif

/**
 * @brief   Enables the EXT subsystem.
 */
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT                 FALSE
#endif

/**
 * @brief   Enables the GPT subsystem.
 */
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT                 FALSE
#endif

/**
 * @brief   Enables the I2C subsystem.
 */
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C                 FALSE
#endif

/**
 * @brief   Enables the ICU subsystem.
 */
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU                 FALSE
#endif

/**
 * @brief   Enables the MAC subsystem.
 */
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC                 FALSE
#endif

/**
 * @brief   Enables the MMC_SPI subsystem.
 */
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI             FALSE
#endif

/**
 * @brief   Enables the PWM subsystem.
 */
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM                 FALSE
#endif

/**
 * @brief   Enables the SDC subsystem.
 */
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC                 FALSE
#endif

/**
 * @brief   Enables the SERIAL subsystem.
 */
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL              FALSE
#endif

/**
 * @brief   Enables the SERIAL over USB subsystem.
 */
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB          FALSE
#endif

/**
 * @brief   Enables the SPI subsystem.
 */
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI                 FALSE
#endif

/**
 * @brief   Enables the UART subsystem.
 */
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART                TRUE
#endif

/**
 * @brief   Enables the USB subsystem.
 */
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB                 FALSE
#endif

/*===========================================================================*/
/* ADC driver related settings.                                              */
/*===========================================================================*/

/**
 * @brief   Enables synchronous APIs.
 * @note    Disabling this option saves both code and data space.
 */
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT                TRUE
#endif

/**
 * @brief   Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
 * @note    Disabling this option saves both code and data space.
 */
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION    TRUE
#endif

/*===========================================================================*/
/* CAN driver related settings.                                              */
/*===========================================================================*/

/**
 * @brief   Sleep mode related APIs inclusion switch.
 */
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE          TRUE
#endif

/*===========================================================================*/
/* I2C driver related settings.                                              */
/*===========================================================================*/

/**
 * @brief   Enables the mutual exclusion APIs on the I2C bus.
 */
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION    TRUE
#endif

/*===========================================================================*/
/* MAC driver related settings.                                              */
/*===========================================================================*/

/*===========================================================================*/
/* MMC_SPI driver related settings.                                          */
/*===========================================================================*/

/**
 * @brief   Block size for MMC transfers.
 */
#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
#define MMC_SECTOR_SIZE             512
#endif

/**
 * @brief   Delays insertions.
 * @details If enabled this options inserts delays into the MMC waiting
 *          routines releasing some extra CPU time for the threads with
 *          lower priority, this may slow down the driver a bit however.
 *          This option is recommended also if the SPI driver does not
 *          use a DMA channel and heavily loads the CPU.
 */
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING            TRUE
#endif

/**
 * @brief   Number of positive insertion queries before generating the
 *          insertion event.
 */
#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
#define MMC_POLLING_INTERVAL        10
#endif

/**
 * @brief   Interval, in milliseconds, between insertion queries.
 */
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
#define MMC_POLLING_DELAY           10
#endif

/**
 * @brief   Uses the SPI polled API for small data transfers.
 * @details Polled transfers usually improve performance because it
 *          saves two context switches and interrupt servicing. Note
 *          that this option has no effect on large transfers which
 *          are always performed using DMAs/IRQs.
 */
#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
#define MMC_USE_SPI_POLLING         TRUE
#endif

/*===========================================================================*/
/* SDC driver related settings.                                              */
/*===========================================================================*/

/**
 * @brief   Number of initialization attempts before rejecting the card.
 * @note    Attempts are performed at 10mS intevals.
 */
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY              100
#endif

/**
 * @brief   Include support for MMC cards.
 * @note    MMC support is not yet implemented so this option must be kept
 *          at @p FALSE.
 */
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT             FALSE
#endif

/**
 * @brief   Delays insertions.
 * @details If enabled this options inserts delays into the MMC waiting
 *          routines releasing some extra CPU time for the threads with
 *          lower priority, this may slow down the driver a bit however.
 */
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING            TRUE
#endif

/*===========================================================================*/
/* SERIAL driver related settings.                                           */
/*===========================================================================*/

/**
 * @brief   Default bit rate.
 * @details Configuration parameter, this is the baud rate selected for the
 *          default configuration.
 */
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE      38400
#endif

/**
 * @brief   Serial buffers size.
 * @details Configuration parameter, you can change the depth of the queue
 *          buffers depending on the requirements of your application.
 * @note    The default is 64 bytes for both the transmission and receive
 *          buffers.
 */
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE         16
#endif

/*===========================================================================*/
/* SPI driver related settings.                                              */
/*===========================================================================*/

/**
 * @brief   Enables synchronous APIs.
 * @note    Disabling this option saves both code and data space.
 */
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT                TRUE
#endif

/**
 * @brief   Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
 * @note    Disabling this option saves both code and data space.
 */
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION    TRUE
#endif

#endif /* _HALCONF_H_ */

/** @} */