|
ChibiOS/RT
2.5.1 |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 00003 2011,2012 Giovanni Di Sirio. 00004 00005 This file is part of ChibiOS/RT. 00006 00007 ChibiOS/RT is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 ChibiOS/RT is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 /** 00022 * @file chbsem.h 00023 * @brief Binary semaphores structures and macros. 00024 * 00025 * @addtogroup binary_semaphores 00026 * @details Binary semaphores related APIs and services. 00027 * 00028 * <h2>Operation mode</h2> 00029 * Binary semaphores are implemented as a set of macros that use the 00030 * existing counting semaphores primitives. The difference between 00031 * counting and binary semaphores is that the counter of binary 00032 * semaphores is not allowed to grow above the value 1. Repeated 00033 * signal operation are ignored. A binary semaphore can thus have 00034 * only two defined states: 00035 * - <b>Taken</b>, when its counter has a value of zero or lower 00036 * than zero. A negative number represent the number of threads 00037 * queued on the binary semaphore. 00038 * - <b>Not taken</b>, when its counter has a value of one. 00039 * . 00040 * Binary semaphores are different from mutexes because there is no 00041 * the concept of ownership, a binary semaphore can be taken by a 00042 * thread and signaled by another thread or an interrupt handler, 00043 * mutexes can only be taken and released by the same thread. Another 00044 * difference is that binary semaphores, unlike mutexes, do not 00045 * implement the priority inheritance protocol.<br> 00046 * In order to use the binary semaphores APIs the @p CH_USE_SEMAPHORES 00047 * option must be enabled in @p chconf.h. 00048 * @{ 00049 */ 00050 00051 #ifndef _CHBSEM_H_ 00052 #define _CHBSEM_H_ 00053 00054 #if CH_USE_SEMAPHORES || defined(__DOXYGEN__) 00055 00056 /** 00057 * @extends Semaphore 00058 * 00059 * @brief Binary semaphore type. 00060 */ 00061 typedef struct { 00062 Semaphore bs_sem; 00063 } BinarySemaphore; 00064 00065 /** 00066 * @brief Data part of a static semaphore initializer. 00067 * @details This macro should be used when statically initializing a semaphore 00068 * that is part of a bigger structure. 00069 * 00070 * @param[in] name the name of the semaphore variable 00071 * @param[in] taken the semaphore initial state 00072 */ 00073 #define _BSEMAPHORE_DATA(name, taken) \ 00074 {_SEMAPHORE_DATA(name.bs_sem, ((taken) ? 0 : 1))} 00075 00076 /** 00077 * @brief Static semaphore initializer. 00078 * @details Statically initialized semaphores require no explicit 00079 * initialization using @p chSemInit(). 00080 * 00081 * @param[in] name the name of the semaphore variable 00082 * @param[in] taken the semaphore initial state 00083 */ 00084 #define BSEMAPHORE_DECL(name, taken) \ 00085 BinarySemaphore name = _BSEMAPHORE_DATA(name, taken) 00086 00087 /** 00088 * @name Macro Functions 00089 * @{ 00090 */ 00091 /** 00092 * @brief Initializes a binary semaphore. 00093 * 00094 * @param[out] bsp pointer to a @p BinarySemaphore structure 00095 * @param[in] taken initial state of the binary semaphore: 00096 * - @a FALSE, the initial state is not taken. 00097 * - @a TRUE, the initial state is taken. 00098 * . 00099 * 00100 * @init 00101 */ 00102 #define chBSemInit(bsp, taken) chSemInit(&(bsp)->bs_sem, (taken) ? 0 : 1) 00103 00104 /** 00105 * @brief Wait operation on the binary semaphore. 00106 * 00107 * @param[in] bsp pointer to a @p BinarySemaphore structure 00108 * @return A message specifying how the invoking thread has been 00109 * released from the semaphore. 00110 * @retval RDY_OK if the binary semaphore has been successfully taken. 00111 * @retval RDY_RESET if the binary semaphore has been reset using 00112 * @p bsemReset(). 00113 * 00114 * @api 00115 */ 00116 #define chBSemWait(bsp) chSemWait(&(bsp)->bs_sem) 00117 00118 /** 00119 * @brief Wait operation on the binary semaphore. 00120 * 00121 * @param[in] bsp pointer to a @p BinarySemaphore structure 00122 * @return A message specifying how the invoking thread has been 00123 * released from the semaphore. 00124 * @retval RDY_OK if the binary semaphore has been successfully taken. 00125 * @retval RDY_RESET if the binary semaphore has been reset using 00126 * @p bsemReset(). 00127 * 00128 * @sclass 00129 */ 00130 #define chBSemWaitS(bsp) chSemWaitS(&(bsp)->bs_sem) 00131 00132 /** 00133 * @brief Wait operation on the binary semaphore. 00134 * 00135 * @param[in] bsp pointer to a @p BinarySemaphore structure 00136 * @param[in] time the number of ticks before the operation timeouts, 00137 * the following special values are allowed: 00138 * - @a TIME_IMMEDIATE immediate timeout. 00139 * - @a TIME_INFINITE no timeout. 00140 * . 00141 * @return A message specifying how the invoking thread has been 00142 * released from the semaphore. 00143 * @retval RDY_OK if the binary semaphore has been successfully taken. 00144 * @retval RDY_RESET if the binary semaphore has been reset using 00145 * @p bsemReset(). 00146 * @retval RDY_TIMEOUT if the binary semaphore has not been signaled or reset 00147 * within the specified timeout. 00148 * 00149 * @api 00150 */ 00151 #define chBSemWaitTimeout(bsp, time) chSemWaitTimeout(&(bsp)->bs_sem, (time)) 00152 00153 /** 00154 * @brief Wait operation on the binary semaphore. 00155 * 00156 * @param[in] bsp pointer to a @p BinarySemaphore structure 00157 * @param[in] time the number of ticks before the operation timeouts, 00158 * the following special values are allowed: 00159 * - @a TIME_IMMEDIATE immediate timeout. 00160 * - @a TIME_INFINITE no timeout. 00161 * . 00162 * @return A message specifying how the invoking thread has been 00163 * released from the semaphore. 00164 * @retval RDY_OK if the binary semaphore has been successfully taken. 00165 * @retval RDY_RESET if the binary semaphore has been reset using 00166 * @p bsemReset(). 00167 * @retval RDY_TIMEOUT if the binary semaphore has not been signaled or reset 00168 * within the specified timeout. 00169 * 00170 * @sclass 00171 */ 00172 #define chBSemWaitTimeoutS(bsp, time) chSemWaitTimeoutS(&(bsp)->bs_sem, (time)) 00173 00174 /** 00175 * @brief Reset operation on the binary semaphore. 00176 * @note The released threads can recognize they were waked up by a reset 00177 * rather than a signal because the @p bsemWait() will return 00178 * @p RDY_RESET instead of @p RDY_OK. 00179 * 00180 * @param[in] bsp pointer to a @p BinarySemaphore structure 00181 * @param[in] taken new state of the binary semaphore 00182 * - @a FALSE, the new state is not taken. 00183 * - @a TRUE, the new state is taken. 00184 * . 00185 * 00186 * @api 00187 */ 00188 #define chBSemReset(bsp, taken) chSemReset(&(bsp)->bs_sem, (taken) ? 0 : 1) 00189 00190 /** 00191 * @brief Reset operation on the binary semaphore. 00192 * @note The released threads can recognize they were waked up by a reset 00193 * rather than a signal because the @p bsemWait() will return 00194 * @p RDY_RESET instead of @p RDY_OK. 00195 * @note This function does not reschedule. 00196 * 00197 * @param[in] bsp pointer to a @p BinarySemaphore structure 00198 * @param[in] taken new state of the binary semaphore 00199 * - @a FALSE, the new state is not taken. 00200 * - @a TRUE, the new state is taken. 00201 * . 00202 * 00203 * @iclass 00204 */ 00205 #define chBSemResetI(bsp, taken) chSemResetI(&(bsp)->bs_sem, (taken) ? 0 : 1) 00206 00207 /** 00208 * @brief Performs a signal operation on a binary semaphore. 00209 * 00210 * @param[in] bsp pointer to a @p BinarySemaphore structure 00211 * 00212 * @api 00213 */ 00214 #define chBSemSignal(bsp) { \ 00215 chSysLock(); \ 00216 chBSemSignalI((bsp)); \ 00217 chSchRescheduleS(); \ 00218 chSysUnlock(); \ 00219 } 00220 00221 /** 00222 * @brief Performs a signal operation on a binary semaphore. 00223 * @note This function does not reschedule. 00224 * 00225 * @param[in] bsp pointer to a @p BinarySemaphore structure 00226 * 00227 * @iclass 00228 */ 00229 #define chBSemSignalI(bsp) { \ 00230 if ((bsp)->bs_sem.s_cnt < 1) \ 00231 chSemSignalI(&(bsp)->bs_sem); \ 00232 } 00233 00234 /** 00235 * @brief Returns the binary semaphore current state. 00236 * 00237 * @param[in] bsp pointer to a @p BinarySemaphore structure 00238 * @return The binary semaphore current state. 00239 * @retval FALSE if the binary semaphore is not taken. 00240 * @retval TRUE if the binary semaphore is taken. 00241 * 00242 * @iclass 00243 */ 00244 #define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE) 00245 /** @} */ 00246 00247 #endif /* CH_USE_SEMAPHORES */ 00248 00249 #endif /* _CHBSEM_H_ */ 00250 00251 /** @} */