ChibiOS/RT Architecture - Reference Manual - Guides |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. 00003 00004 This file is part of ChibiOS/RT. 00005 00006 ChibiOS/RT is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 ChibiOS/RT is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 --- 00020 00021 A special exception to the GPL can be applied should you wish to distribute 00022 a combined work that includes ChibiOS/RT, without being obliged to provide 00023 the source code for any proprietary components. See the file exception.txt 00024 for full details of how and when the exception can be applied. 00025 */ 00026 00027 /** 00028 * @file chqueues.h I/O 00029 * @brief Queues macros and structures. 00030 * 00031 * @addtogroup io_queues 00032 * @{ 00033 */ 00034 00035 #ifndef _CHQUEUES_H_ 00036 #define _CHQUEUES_H_ 00037 00038 #if CH_USE_QUEUES 00039 00040 /* 00041 * Module dependencies check. 00042 */ 00043 #if !CH_USE_SEMAPHORES 00044 #error "CH_USE_QUEUES requires CH_USE_SEMAPHORES" 00045 #endif 00046 00047 /** @brief Queue notification callback type.*/ 00048 typedef void (*qnotify_t)(void); 00049 00050 /** @brief Returned by the queue functions if the operation is successful.*/ 00051 #define Q_OK RDY_OK 00052 /** @brief Returned by the queue functions if a timeout occurs.*/ 00053 #define Q_TIMEOUT RDY_TIMEOUT 00054 /** @brief Returned by the queue functions if the queue is reset.*/ 00055 #define Q_RESET RDY_RESET 00056 /** @brief Returned by the queue functions if the queue is empty.*/ 00057 #define Q_EMPTY -3 00058 /** @brief Returned by the queue functions if the queue is full.*/ 00059 #define Q_FULL -4 00060 00061 /** 00062 * @brief Generic I/O queue structure. 00063 * @details This structure represents a generic Input or Output asymmetrical 00064 * queue. The queue is asymmetrical because one end is meant to be 00065 * accessed from a thread context, and thus can be blocking, the other 00066 * end is accessible from interrupt handlers or from within a kernel 00067 * lock zone (see <b>I-Locked</b> and <b>S-Locked</b> states in 00068 * @ref system_states) and is non-blocking. 00069 */ 00070 typedef struct { 00071 uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/ 00072 uint8_t *q_top; /**< @brief Pointer to the first location 00073 after the buffer. */ 00074 uint8_t *q_wrptr; /**< @brief Write pointer. */ 00075 uint8_t *q_rdptr; /**< @brief Read pointer. */ 00076 Semaphore q_sem; /**< @brief Counter @p Semaphore. */ 00077 qnotify_t q_notify; /**< @brief Data notification callback. */ 00078 } GenericQueue; 00079 00080 /** 00081 * @brief Returns the queue's buffer size. 00082 */ 00083 #define chQSize(q) ((q)->q_top - (q)->q_buffer) 00084 00085 /** 00086 * @brief Queue space. 00087 * @details Returns the used space if used on an Input Queue and the empty 00088 * space if used on an Output Queue. 00089 * @note The returned value can be less than zero when there are waiting 00090 * threads on the internal semaphore. 00091 */ 00092 #define chQSpace(q) chSemGetCounterI(&(q)->q_sem) 00093 00094 /** 00095 * @extends GenericQueue 00096 * 00097 * @brief Input queue structure. 00098 * @details This structure represents a generic asymmetrical input queue. 00099 * Writing in the queue is non-blocking and can be performed from 00100 * interrupt handlers or from within a kernel lock zone (see 00101 * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states). 00102 * Reading the queue can be a blocking operation and is supposed to 00103 * be performed by a system thread. 00104 */ 00105 typedef GenericQueue InputQueue; 00106 00107 /** @brief Evaluates to @p TRUE if the specified Input Queue is empty.*/ 00108 #define chIQIsEmpty(q) ((bool_t)(chQSpace(q) <= 0)) 00109 00110 /** @brief Evaluates to @p TRUE if the specified Input Queue is full.*/ 00111 #define chIQIsFull(q) ((bool_t)(chQSpace(q) >= chQSize(q))) 00112 00113 /** 00114 * @brief Input queue read. 00115 * @details This function reads a byte value from an input queue. If the queue 00116 * is empty then the calling thread is suspended until a byte arrives 00117 * in the queue. 00118 * 00119 * @param[in] iqp pointer to an @p InputQueue structure 00120 * @return A byte value from the queue or: 00121 * @retval Q_RESET if the queue was reset. 00122 */ 00123 #define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE) 00124 00125 /** 00126 * @brief Data part of a static input queue initializer. 00127 * @details This macro should be used when statically initializing an 00128 * input queue that is part of a bigger structure. 00129 * 00130 * @param[in] name the name of the input queue variable 00131 * @param[in] buffer pointer to the queue buffer area 00132 * @param[in] size size of the queue buffer area 00133 * @param[in] inotify input notification callback pointer 00134 */ 00135 #define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \ 00136 (uint8_t *)(buffer), \ 00137 (uint8_t *)(buffer) + size, \ 00138 (uint8_t *)(buffer), \ 00139 (uint8_t *)(buffer), \ 00140 _SEMAPHORE_DATA(name.q_sem, 0), \ 00141 inotify \ 00142 } 00143 00144 /** 00145 * @brief Static input queue initializer. 00146 * @details Statically initialized input queues require no explicit 00147 * initialization using @p chIQInit(). 00148 * 00149 * @param[in] name the name of the input queue variable 00150 * @param[in] buffer pointer to the queue buffer area 00151 * @param[in] size size of the queue buffer area 00152 * @param[in] inotify input notification callback pointer 00153 */ 00154 #define INPUTQUEUE_DECL(name, buffer, size, inotify) \ 00155 InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify) 00156 00157 /** 00158 * @extends GenericQueue 00159 * 00160 * @brief Output queue structure. 00161 * @details This structure represents a generic asymmetrical output queue. 00162 * Reading from the queue is non-blocking and can be performed from 00163 * interrupt handlers or from within a kernel lock zone (see 00164 * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states). 00165 * Writing the queue can be a blocking operation and is supposed to 00166 * be performed by a system thread. 00167 */ 00168 typedef GenericQueue OutputQueue; 00169 00170 /** 00171 * @brief Evaluates to @p TRUE if the specified Output Queue is empty. 00172 */ 00173 #define chOQIsEmpty(q) ((bool_t)(chQSpace(q) >= chQSize(q))) 00174 00175 /** 00176 * @brief Evaluates to @p TRUE if the specified Output Queue is full. 00177 */ 00178 #define chOQIsFull(q) ((bool_t)(chQSpace(q) <= 0)) 00179 00180 /** 00181 * @brief Output queue write. 00182 * @details This function writes a byte value to an output queue. If the queue 00183 * is full then the calling thread is suspended until there is space 00184 * in the queue. 00185 * 00186 * @param[in] oqp pointer to an @p OutputQueue structure 00187 * @param[in] b the byte value to be written in the queue 00188 * @return The operation status: 00189 * @retval Q_OK if the operation succeeded. 00190 * @retval Q_RESET if the queue was reset. 00191 */ 00192 #define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE) 00193 00194 /** 00195 * @brief Data part of a static output queue initializer. 00196 * @details This macro should be used when statically initializing an 00197 * output queue that is part of a bigger structure. 00198 * 00199 * @param[in] name the name of the output queue variable. 00200 * @param[in] buffer pointer to the queue buffer area 00201 * @param[in] size size of the queue buffer area 00202 * @param[in] onotify output notification callback pointer 00203 */ 00204 #define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \ 00205 (uint8_t *)(buffer), \ 00206 (uint8_t *)(buffer) + size, \ 00207 (uint8_t *)(buffer), \ 00208 (uint8_t *)(buffer), \ 00209 _SEMAPHORE_DATA(name.q_sem, size), \ 00210 onotify \ 00211 } 00212 00213 /** 00214 * @brief Static output queue initializer. 00215 * @details Statically initialized output queues require no explicit 00216 * initialization using @p chOQInit(). 00217 * 00218 * @param[in] name the name of the output queue variable 00219 * @param[in] buffer pointer to the queue buffer area 00220 * @param[in] size size of the queue buffer area 00221 * @param[in] onotify output notification callback pointer 00222 */ 00223 #define OUTPUTQUEUE_DECL(name, buffer, size, onotify) \ 00224 InputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify) 00225 00226 #ifdef __cplusplus 00227 extern "C" { 00228 #endif 00229 void chIQInit(InputQueue *qp, uint8_t *bp, size_t size, qnotify_t infy); 00230 void chIQResetI(InputQueue *qp); 00231 msg_t chIQPutI(InputQueue *qp, uint8_t b); 00232 msg_t chIQGetTimeout(InputQueue *qp, systime_t time); 00233 size_t chIQReadTimeout(InputQueue *qp, uint8_t *bp, 00234 size_t n, systime_t time); 00235 00236 void chOQInit(OutputQueue *queue, uint8_t *bp, size_t size, qnotify_t onfy); 00237 void chOQResetI(OutputQueue *queue); 00238 msg_t chOQPutTimeout(OutputQueue *queue, uint8_t b, systime_t time); 00239 msg_t chOQGetI(OutputQueue *queue); 00240 size_t chOQWriteTimeout(OutputQueue *queue, const uint8_t *bp, 00241 size_t n, systime_t time); 00242 #ifdef __cplusplus 00243 } 00244 #endif 00245 #endif /* CH_USE_QUEUES */ 00246 00247 #endif /* _CHQUEUES_H_ */ 00248 00249 /** @} */