|
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 chthreads.h 00023 * @brief Threads macros and structures. 00024 * 00025 * @addtogroup threads 00026 * @{ 00027 */ 00028 00029 #ifndef _CHTHREADS_H_ 00030 #define _CHTHREADS_H_ 00031 00032 /** 00033 * @name Thread states 00034 * @{ 00035 */ 00036 #define THD_STATE_READY 0 /**< @brief Waiting on the ready list. */ 00037 #define THD_STATE_CURRENT 1 /**< @brief Currently running. */ 00038 #define THD_STATE_SUSPENDED 2 /**< @brief Created in suspended state. */ 00039 #define THD_STATE_WTSEM 3 /**< @brief Waiting on a semaphore. */ 00040 #define THD_STATE_WTMTX 4 /**< @brief Waiting on a mutex. */ 00041 #define THD_STATE_WTCOND 5 /**< @brief Waiting on a condition 00042 variable. */ 00043 #define THD_STATE_SLEEPING 6 /**< @brief Waiting in @p chThdSleep() 00044 or @p chThdSleepUntil(). */ 00045 #define THD_STATE_WTEXIT 7 /**< @brief Waiting in @p chThdWait(). */ 00046 #define THD_STATE_WTOREVT 8 /**< @brief Waiting for an event. */ 00047 #define THD_STATE_WTANDEVT 9 /**< @brief Waiting for several events. */ 00048 #define THD_STATE_SNDMSGQ 10 /**< @brief Sending a message, in queue.*/ 00049 #define THD_STATE_SNDMSG 11 /**< @brief Sent a message, waiting 00050 answer. */ 00051 #define THD_STATE_WTMSG 12 /**< @brief Waiting for a message. */ 00052 #define THD_STATE_WTQUEUE 13 /**< @brief Waiting on an I/O queue. */ 00053 #define THD_STATE_FINAL 14 /**< @brief Thread terminated. */ 00054 00055 /** 00056 * @brief Thread states as array of strings. 00057 * @details Each element in an array initialized with this macro can be 00058 * indexed using the numeric thread state values. 00059 */ 00060 #define THD_STATE_NAMES \ 00061 "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING", \ 00062 "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE", \ 00063 "FINAL" 00064 /** @} */ 00065 00066 /** 00067 * @name Thread flags and attributes 00068 * @{ 00069 */ 00070 #define THD_MEM_MODE_MASK 3 /**< @brief Thread memory mode mask. */ 00071 #define THD_MEM_MODE_STATIC 0 /**< @brief Static thread. */ 00072 #define THD_MEM_MODE_HEAP 1 /**< @brief Thread allocated from a 00073 Memory Heap. */ 00074 #define THD_MEM_MODE_MEMPOOL 2 /**< @brief Thread allocated from a 00075 Memory Pool. */ 00076 #define THD_TERMINATE 4 /**< @brief Termination requested flag. */ 00077 /** @} */ 00078 00079 /** 00080 * @extends ThreadsQueue 00081 * 00082 * @brief Structure representing a thread. 00083 * @note Not all the listed fields are always needed, by switching off some 00084 * not needed ChibiOS/RT subsystems it is possible to save RAM space 00085 * by shrinking the @p Thread structure. 00086 */ 00087 struct Thread { 00088 Thread *p_next; /**< @brief Next in the list/queue. */ 00089 /* End of the fields shared with the ThreadsList structure. */ 00090 Thread *p_prev; /**< @brief Previous in the queue. */ 00091 /* End of the fields shared with the ThreadsQueue structure. */ 00092 tprio_t p_prio; /**< @brief Thread priority. */ 00093 struct context p_ctx; /**< @brief Processor context. */ 00094 #if CH_USE_REGISTRY || defined(__DOXYGEN__) 00095 Thread *p_newer; /**< @brief Newer registry element. */ 00096 Thread *p_older; /**< @brief Older registry element. */ 00097 #endif 00098 /* End of the fields shared with the ReadyList structure. */ 00099 #if CH_USE_REGISTRY || defined(__DOXYGEN__) 00100 /** 00101 * @brief Thread name or @p NULL. 00102 */ 00103 const char *p_name; 00104 #endif 00105 #if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) 00106 /** 00107 * @brief Thread stack boundary. 00108 */ 00109 stkalign_t *p_stklimit; 00110 #endif 00111 /** 00112 * @brief Current thread state. 00113 */ 00114 tstate_t p_state; 00115 /** 00116 * @brief Various thread flags. 00117 */ 00118 tmode_t p_flags; 00119 #if CH_USE_DYNAMIC || defined(__DOXYGEN__) 00120 /** 00121 * @brief References to this thread. 00122 */ 00123 trefs_t p_refs; 00124 #endif 00125 /** 00126 * @brief Number of ticks remaining to this thread. 00127 */ 00128 #if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__) 00129 tslices_t p_preempt; 00130 #endif 00131 #if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__) 00132 /** 00133 * @brief Thread consumed time in ticks. 00134 * @note This field can overflow. 00135 */ 00136 volatile systime_t p_time; 00137 #endif 00138 /** 00139 * @brief State-specific fields. 00140 * @note All the fields declared in this union are only valid in the 00141 * specified state or condition and are thus volatile. 00142 */ 00143 union { 00144 /** 00145 * @brief Thread wakeup code. 00146 * @note This field contains the low level message sent to the thread 00147 * by the waking thread or interrupt handler. The value is valid 00148 * after exiting the @p chSchWakeupS() function. 00149 */ 00150 msg_t rdymsg; 00151 /** 00152 * @brief Thread exit code. 00153 * @note The thread termination code is stored in this field in order 00154 * to be retrieved by the thread performing a @p chThdWait() on 00155 * this thread. 00156 */ 00157 msg_t exitcode; 00158 /** 00159 * @brief Pointer to a generic "wait" object. 00160 * @note This field is used to get a generic pointer to a synchronization 00161 * object and is valid when the thread is in one of the wait 00162 * states. 00163 */ 00164 void *wtobjp; 00165 #if CH_USE_EVENTS || defined(__DOXYGEN__) 00166 /** 00167 * @brief Enabled events mask. 00168 * @note This field is only valid while the thread is in the 00169 * @p THD_STATE_WTOREVT or @p THD_STATE_WTANDEVT states. 00170 */ 00171 eventmask_t ewmask; 00172 #endif 00173 } p_u; 00174 #if CH_USE_WAITEXIT || defined(__DOXYGEN__) 00175 /** 00176 * @brief Termination waiting list. 00177 */ 00178 ThreadsList p_waiting; 00179 #endif 00180 #if CH_USE_MESSAGES || defined(__DOXYGEN__) 00181 /** 00182 * @brief Messages queue. 00183 */ 00184 ThreadsQueue p_msgqueue; 00185 /** 00186 * @brief Thread message. 00187 */ 00188 msg_t p_msg; 00189 #endif 00190 #if CH_USE_EVENTS || defined(__DOXYGEN__) 00191 /** 00192 * @brief Pending events mask. 00193 */ 00194 eventmask_t p_epending; 00195 #endif 00196 #if CH_USE_MUTEXES || defined(__DOXYGEN__) 00197 /** 00198 * @brief List of the mutexes owned by this thread. 00199 * @note The list is terminated by a @p NULL in this field. 00200 */ 00201 Mutex *p_mtxlist; 00202 /** 00203 * @brief Thread's own, non-inherited, priority. 00204 */ 00205 tprio_t p_realprio; 00206 #endif 00207 #if (CH_USE_DYNAMIC && CH_USE_MEMPOOLS) || defined(__DOXYGEN__) 00208 /** 00209 * @brief Memory Pool where the thread workspace is returned. 00210 */ 00211 void *p_mpool; 00212 #endif 00213 #if defined(THREAD_EXT_FIELDS) 00214 /* Extra fields defined in chconf.h.*/ 00215 THREAD_EXT_FIELDS 00216 #endif 00217 }; 00218 00219 /** 00220 * @brief Thread function. 00221 */ 00222 typedef msg_t (*tfunc_t)(void *); 00223 00224 /** 00225 * @name Macro Functions 00226 * @{ 00227 */ 00228 /** 00229 * @brief Returns a pointer to the current @p Thread. 00230 * @note Can be invoked in any context. 00231 * 00232 * @special 00233 */ 00234 #define chThdSelf() currp 00235 00236 /** 00237 * @brief Returns the current thread priority. 00238 * @note Can be invoked in any context. 00239 * 00240 * @special 00241 */ 00242 #define chThdGetPriority() (currp->p_prio) 00243 00244 /** 00245 * @brief Returns the number of ticks consumed by the specified thread. 00246 * @note This function is only available when the 00247 * @p CH_DBG_THREADS_PROFILING configuration option is enabled. 00248 * @note Can be invoked in any context. 00249 * 00250 * @param[in] tp pointer to the thread 00251 * 00252 * @special 00253 */ 00254 #define chThdGetTicks(tp) ((tp)->p_time) 00255 00256 /** 00257 * @brief Returns the pointer to the @p Thread local storage area, if any. 00258 * @note Can be invoked in any context. 00259 * 00260 * @special 00261 */ 00262 #define chThdLS() (void *)(currp + 1) 00263 00264 /** 00265 * @brief Verifies if the specified thread is in the @p THD_STATE_FINAL state. 00266 * @note Can be invoked in any context. 00267 * 00268 * @param[in] tp pointer to the thread 00269 * @retval TRUE thread terminated. 00270 * @retval FALSE thread not terminated. 00271 * 00272 * @special 00273 */ 00274 #define chThdTerminated(tp) ((tp)->p_state == THD_STATE_FINAL) 00275 00276 /** 00277 * @brief Verifies if the current thread has a termination request pending. 00278 * @note Can be invoked in any context. 00279 * 00280 * @retval TRUE termination request pending. 00281 * @retval FALSE termination request not pending. 00282 * 00283 * @special 00284 */ 00285 #define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE) 00286 00287 /** 00288 * @brief Resumes a thread created with @p chThdCreateI(). 00289 * 00290 * @param[in] tp pointer to the thread 00291 * 00292 * @iclass 00293 */ 00294 #define chThdResumeI(tp) chSchReadyI(tp) 00295 00296 /** 00297 * @brief Suspends the invoking thread for the specified time. 00298 * 00299 * @param[in] time the delay in system ticks, the special values are 00300 * handled as follow: 00301 * - @a TIME_INFINITE the thread enters an infinite sleep 00302 * state. 00303 * - @a TIME_IMMEDIATE this value is not allowed. 00304 * . 00305 * 00306 * @sclass 00307 */ 00308 #define chThdSleepS(time) chSchGoSleepTimeoutS(THD_STATE_SLEEPING, time) 00309 00310 /** 00311 * @brief Delays the invoking thread for the specified number of seconds. 00312 * @note The specified time is rounded up to a value allowed by the real 00313 * system clock. 00314 * @note The maximum specified value is implementation dependent. 00315 * 00316 * @param[in] sec time in seconds, must be different from zero 00317 * 00318 * @api 00319 */ 00320 #define chThdSleepSeconds(sec) chThdSleep(S2ST(sec)) 00321 00322 /** 00323 * @brief Delays the invoking thread for the specified number of 00324 * milliseconds. 00325 * @note The specified time is rounded up to a value allowed by the real 00326 * system clock. 00327 * @note The maximum specified value is implementation dependent. 00328 * 00329 * @param[in] msec time in milliseconds, must be different from zero 00330 * 00331 * @api 00332 */ 00333 #define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec)) 00334 00335 /** 00336 * @brief Delays the invoking thread for the specified number of 00337 * microseconds. 00338 * @note The specified time is rounded up to a value allowed by the real 00339 * system clock. 00340 * @note The maximum specified value is implementation dependent. 00341 * 00342 * @param[in] usec time in microseconds, must be different from zero 00343 * 00344 * @api 00345 */ 00346 #define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec)) 00347 /** @} */ 00348 00349 /* 00350 * Threads APIs. 00351 */ 00352 #ifdef __cplusplus 00353 extern "C" { 00354 #endif 00355 Thread *_thread_init(Thread *tp, tprio_t prio); 00356 #if CH_DBG_FILL_THREADS 00357 void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v); 00358 #endif 00359 Thread *chThdCreateI(void *wsp, size_t size, 00360 tprio_t prio, tfunc_t pf, void *arg); 00361 Thread *chThdCreateStatic(void *wsp, size_t size, 00362 tprio_t prio, tfunc_t pf, void *arg); 00363 tprio_t chThdSetPriority(tprio_t newprio); 00364 Thread *chThdResume(Thread *tp); 00365 void chThdTerminate(Thread *tp); 00366 void chThdSleep(systime_t time); 00367 void chThdSleepUntil(systime_t time); 00368 void chThdYield(void); 00369 void chThdExit(msg_t msg); 00370 void chThdExitS(msg_t msg); 00371 #if CH_USE_WAITEXIT 00372 msg_t chThdWait(Thread *tp); 00373 #endif 00374 #ifdef __cplusplus 00375 } 00376 #endif 00377 00378 #endif /* _CHTHREADS_H_ */ 00379 00380 /** @} */