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 chthreads.h 00029 * @brief Threads macros and structures. 00030 * 00031 * @addtogroup threads 00032 * @{ 00033 */ 00034 00035 #ifndef _CHTHREADS_H_ 00036 #define _CHTHREADS_H_ 00037 00038 /* 00039 * Module dependencies check. 00040 */ 00041 #if CH_USE_DYNAMIC && !CH_USE_WAITEXIT 00042 #error "CH_USE_DYNAMIC requires CH_USE_WAITEXIT" 00043 #endif 00044 #if CH_USE_DYNAMIC && !CH_USE_HEAP && !CH_USE_MEMPOOLS 00045 #error "CH_USE_DYNAMIC requires CH_USE_HEAP and/or CH_USE_MEMPOOLS" 00046 #endif 00047 00048 /** 00049 * @extends ThreadsQueue 00050 * 00051 * @brief Structure representing a thread. 00052 * @note Not all the listed fields are always needed, by switching off some 00053 * not needed ChibiOS/RT subsystems it is possible to save RAM space 00054 * by shrinking the @p Thread structure. 00055 */ 00056 struct Thread { 00057 Thread *p_next; /**< @brief Next in the list/queue. */ 00058 /* End of the fields shared with the ThreadsList structure. */ 00059 Thread *p_prev; /**< @brief Previous in the queue. */ 00060 /* End of the fields shared with the ThreadsQueue structure. */ 00061 tprio_t p_prio; /**< @brief Thread priority. */ 00062 struct context p_ctx; /**< @brief Processor context. */ 00063 #if CH_USE_REGISTRY 00064 Thread *p_newer; /**< @brief Newer registry element. */ 00065 Thread *p_older; /**< @brief Older registry element. */ 00066 #endif 00067 /* End of the fields shared with the ReadyList structure. */ 00068 /** 00069 * @brief Current thread state. 00070 */ 00071 tstate_t p_state; 00072 /** 00073 * @brief Various thread flags. 00074 */ 00075 tmode_t p_flags; 00076 #if CH_USE_DYNAMIC 00077 /** 00078 * @brief References to this thread. 00079 */ 00080 trefs_t p_refs; 00081 #endif 00082 #if CH_USE_NESTED_LOCKS 00083 /** 00084 * @brief Number of nested locks. 00085 */ 00086 cnt_t p_locks; 00087 #endif 00088 #if CH_DBG_THREADS_PROFILING 00089 /** 00090 * @brief Thread consumed time in ticks. 00091 * @note This field can overflow. 00092 */ 00093 volatile systime_t p_time; 00094 #endif 00095 /** 00096 * @brief State-specific fields. 00097 * @note All the fields declared in this union are only valid in the 00098 * specified state or condition and are thus volatile. 00099 */ 00100 union { 00101 /** 00102 * @brief Thread wakeup code. 00103 * @note This field contains the low level message sent to the thread 00104 * by the waking thread or interrupt handler. The value is valid 00105 * after exiting the @p chSchWakeupS() function. 00106 */ 00107 msg_t rdymsg; 00108 /** 00109 * @brief Thread exit code. 00110 * @note The thread termination code is stored in this field in order 00111 * to be retrieved by the thread performing a @p chThdWait() on 00112 * this thread. 00113 */ 00114 msg_t exitcode; 00115 /** 00116 * @brief Pointer to a generic "wait" object. 00117 * @note This field is used to get a generic pointer to a synchronization 00118 * object and is valid when the thread is in one of the wait 00119 * states. 00120 */ 00121 void *wtobjp; 00122 #if CH_USE_EVENTS 00123 /** 00124 * @brief Enabled events mask. 00125 * @note This field is only valied while the thread is in the 00126 * @p THD_STATE_WTOREVT or @p THD_STATE_WTANDEVT states. 00127 */ 00128 eventmask_t ewmask; 00129 #endif 00130 } p_u; 00131 #if CH_USE_WAITEXIT 00132 /** 00133 * @brief Termination waiting list. 00134 */ 00135 ThreadsList p_waiting; 00136 #endif 00137 #if CH_USE_MESSAGES 00138 /** 00139 * @brief Messages queue. 00140 */ 00141 ThreadsQueue p_msgqueue; 00142 /** 00143 * @brief Thread message. 00144 */ 00145 msg_t p_msg; 00146 #endif 00147 #if CH_USE_EVENTS 00148 /** 00149 * @brief Pending events mask. 00150 */ 00151 eventmask_t p_epending; 00152 #endif 00153 #if CH_USE_MUTEXES 00154 /** 00155 * @brief List of the mutexes owned by this thread. 00156 * @note The list is terminated by a @p NULL in this field. 00157 */ 00158 Mutex *p_mtxlist; 00159 /** 00160 * @brief Thread's own, non-inherited, priority. 00161 */ 00162 tprio_t p_realprio; 00163 #endif 00164 #if CH_USE_DYNAMIC && CH_USE_MEMPOOLS 00165 /** 00166 * @brief Memory Pool where the thread workspace is returned. 00167 */ 00168 void *p_mpool; 00169 #endif 00170 /* Extra fields defined in chconf.h.*/ 00171 THREAD_EXT_FIELDS 00172 }; 00173 00174 /** @brief Thread state: Ready to run, waiting on the ready list.*/ 00175 #define THD_STATE_READY 0 00176 /** @brief Thread state: Currently running.*/ 00177 #define THD_STATE_CURRENT 1 00178 /** @brief Thread state: Thread created in suspended state.*/ 00179 #define THD_STATE_SUSPENDED 2 00180 /** @brief Thread state: Waiting on a semaphore.*/ 00181 #define THD_STATE_WTSEM 3 00182 /** @brief Thread state: Waiting on a mutex.*/ 00183 #define THD_STATE_WTMTX 4 00184 /** @brief Thread state: Waiting in @p chCondWait().*/ 00185 #define THD_STATE_WTCOND 5 00186 /** @brief Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil().*/ 00187 #define THD_STATE_SLEEPING 6 00188 /** @brief Thread state: Waiting in @p chThdWait().*/ 00189 #define THD_STATE_WTEXIT 7 00190 /** @brief Thread state: Waiting in @p chEvtWaitXXX().*/ 00191 #define THD_STATE_WTOREVT 8 00192 /** @brief Thread state: Waiting in @p chEvtWaitAllTimeout().*/ 00193 #define THD_STATE_WTANDEVT 9 00194 /** @brief Thread state: Waiting in @p chMsgSend().*/ 00195 #define THD_STATE_SNDMSG 10 00196 /** @brief Thread state: Waiting in @p chMsgWait().*/ 00197 #define THD_STATE_WTMSG 11 00198 /** @brief Thread state: After termination.*/ 00199 #define THD_STATE_FINAL 12 00200 00201 /* 00202 * Various flags into the thread p_flags field. 00203 */ 00204 #define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */ 00205 #define THD_MEM_MODE_STATIC 0 /**< @brief Thread memory mode: static. */ 00206 #define THD_MEM_MODE_HEAP 1 /**< @brief Thread memory mode: heap. */ 00207 #define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread memory mode: pool. */ 00208 #define THD_TERMINATE 4 /**< @brief Termination requested. */ 00209 00210 /** @brief Thread function.*/ 00211 typedef msg_t (*tfunc_t)(void *); 00212 00213 /* 00214 * Threads APIs. 00215 */ 00216 #ifdef __cplusplus 00217 extern "C" { 00218 #endif 00219 Thread *init_thread(Thread *tp, tprio_t prio); 00220 Thread *chThdInit(void *wsp, size_t size, 00221 tprio_t prio, tfunc_t pf, void *arg); 00222 Thread *chThdCreateStatic(void *wsp, size_t size, 00223 tprio_t prio, tfunc_t pf, void *arg); 00224 #if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP 00225 Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, 00226 tprio_t prio, tfunc_t pf, void *arg); 00227 #endif 00228 #if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS 00229 Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, 00230 tfunc_t pf, void *arg); 00231 #endif 00232 tprio_t chThdSetPriority(tprio_t newprio); 00233 Thread *chThdResume(Thread *tp); 00234 void chThdTerminate(Thread *tp); 00235 void chThdSleep(systime_t time); 00236 void chThdSleepUntil(systime_t time); 00237 void chThdYield(void); 00238 void chThdExit(msg_t msg); 00239 #if CH_USE_DYNAMIC 00240 Thread *chThdAddRef(Thread *tp); 00241 void chThdRelease(Thread *tp); 00242 #endif 00243 #if CH_USE_WAITEXIT 00244 msg_t chThdWait(Thread *tp); 00245 #endif 00246 #ifdef __cplusplus 00247 } 00248 #endif 00249 00250 /** 00251 * @brief Returns a pointer to the current @p Thread. 00252 */ 00253 #define chThdSelf() currp 00254 00255 /** 00256 * @brief Returns the current thread priority. 00257 */ 00258 #define chThdGetPriority() (currp->p_prio) 00259 00260 /** 00261 * @brief Returns the pointer to the @p Thread local storage area, if any. 00262 */ 00263 #define chThdLS() (void *)(currp + 1) 00264 00265 /** 00266 * @brief Verifies if the specified thread is in the @p THD_STATE_FINAL state. 00267 * 00268 * @param[in] tp the pointer to the thread 00269 * @retval TRUE thread terminated. 00270 * @retval FALSE thread not terminated. 00271 */ 00272 #define chThdTerminated(tp) ((tp)->p_state == THD_STATE_FINAL) 00273 00274 /** 00275 * @brief Verifies if the current thread has a termination request pending. 00276 * 00277 * @retval TRUE termination request pended. 00278 * @retval FALSE termination request not pended. 00279 */ 00280 #define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE) 00281 00282 /** 00283 * @brief Resumes a thread created with @p chThdInit(). 00284 * 00285 * @param[in] tp the pointer to the thread 00286 */ 00287 #define chThdResumeI(tp) chSchReadyI(tp) 00288 00289 /** 00290 * @brief Suspends the invoking thread for the specified time. 00291 * 00292 * @param[in] time the delay in system ticks, the special values are 00293 * handled as follow: 00294 * - @a TIME_INFINITE the thread enters an infinite sleep 00295 * state. 00296 * - @a TIME_IMMEDIATE this value is accepted but 00297 * interpreted as a normal time specification not as 00298 * an immediate timeout specification. 00299 * . 00300 */ 00301 #define chThdSleepS(time) chSchGoSleepTimeoutS(THD_STATE_SLEEPING, time) 00302 00303 /** 00304 * @brief Delays the invoking thread for the specified number of seconds. 00305 * @note The specified time is rounded up to a value allowed by the real 00306 * system clock. 00307 * @note The maximum specified value is implementation dependent. 00308 * 00309 * @param[in] sec the time in seconds 00310 */ 00311 #define chThdSleepSeconds(sec) chThdSleep(S2ST(sec)) 00312 00313 /** 00314 * @brief Delays the invoking thread for the specified number of 00315 * milliseconds. 00316 * @note The specified time is rounded up to a value allowed by the real 00317 * system clock. 00318 * @note The maximum specified value is implementation dependent. 00319 * 00320 * @param[in] msec the time in milliseconds 00321 */ 00322 #define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec)) 00323 00324 /** 00325 * @brief Delays the invoking thread for the specified number of 00326 * microseconds. 00327 * @note The specified time is rounded up to a value allowed by the real 00328 * system clock. 00329 * @note The maximum specified value is implementation dependent. 00330 * 00331 * @param[in] usec the time in microseconds 00332 */ 00333 #define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec)) 00334 00335 #endif /* _CHTHREADS_H_ */ 00336 00337 /** @} */