|
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 chvt.h 00023 * @brief Time macros and structures. 00024 * 00025 * @addtogroup time 00026 * @{ 00027 */ 00028 00029 #ifndef _CHVT_H_ 00030 #define _CHVT_H_ 00031 00032 /** 00033 * @name Time conversion utilities 00034 * @{ 00035 */ 00036 /** 00037 * @brief Seconds to system ticks. 00038 * @details Converts from seconds to system ticks number. 00039 * @note The result is rounded upward to the next tick boundary. 00040 * 00041 * @param[in] sec number of seconds 00042 * @return The number of ticks. 00043 * 00044 * @api 00045 */ 00046 #define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY)) 00047 00048 /** 00049 * @brief Milliseconds to system ticks. 00050 * @details Converts from milliseconds to system ticks number. 00051 * @note The result is rounded upward to the next tick boundary. 00052 * 00053 * @param[in] msec number of milliseconds 00054 * @return The number of ticks. 00055 * 00056 * @api 00057 */ 00058 #define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / \ 00059 1000L) + 1L)) 00060 00061 /** 00062 * @brief Microseconds to system ticks. 00063 * @details Converts from microseconds to system ticks number. 00064 * @note The result is rounded upward to the next tick boundary. 00065 * 00066 * @param[in] usec number of microseconds 00067 * @return The number of ticks. 00068 * 00069 * @api 00070 */ 00071 #define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / \ 00072 1000000L) + 1L)) 00073 /** @} */ 00074 00075 /** 00076 * @brief Virtual Timer callback function. 00077 */ 00078 typedef void (*vtfunc_t)(void *); 00079 00080 /** 00081 * @brief Virtual Timer structure type. 00082 */ 00083 typedef struct VirtualTimer VirtualTimer; 00084 00085 /** 00086 * @extends DeltaList 00087 * 00088 * @brief Virtual Timer descriptor structure. 00089 */ 00090 struct VirtualTimer { 00091 VirtualTimer *vt_next; /**< @brief Next timer in the delta 00092 list. */ 00093 VirtualTimer *vt_prev; /**< @brief Previous timer in the delta 00094 list. */ 00095 systime_t vt_time; /**< @brief Time delta before timeout. */ 00096 vtfunc_t vt_func; /**< @brief Timer callback function 00097 pointer. */ 00098 void *vt_par; /**< @brief Timer callback function 00099 parameter. */ 00100 }; 00101 00102 /** 00103 * @brief Virtual timers list header. 00104 * @note The delta list is implemented as a double link bidirectional list 00105 * in order to make the unlink time constant, the reset of a virtual 00106 * timer is often used in the code. 00107 */ 00108 typedef struct { 00109 VirtualTimer *vt_next; /**< @brief Next timer in the delta 00110 list. */ 00111 VirtualTimer *vt_prev; /**< @brief Last timer in the delta 00112 list. */ 00113 systime_t vt_time; /**< @brief Must be initialized to -1. */ 00114 volatile systime_t vt_systime; /**< @brief System Time counter. */ 00115 } VTList; 00116 00117 /** 00118 * @name Macro Functions 00119 * @{ 00120 */ 00121 /** 00122 * @brief Virtual timers ticker. 00123 * @note The system lock is released before entering the callback and 00124 * re-acquired immediately after. It is callback's responsibility 00125 * to acquire the lock if needed. This is done in order to reduce 00126 * interrupts jitter when many timers are in use. 00127 * 00128 * @iclass 00129 */ 00130 #define chVTDoTickI() { \ 00131 vtlist.vt_systime++; \ 00132 if (&vtlist != (VTList *)vtlist.vt_next) { \ 00133 VirtualTimer *vtp; \ 00134 \ 00135 --vtlist.vt_next->vt_time; \ 00136 while (!(vtp = vtlist.vt_next)->vt_time) { \ 00137 vtfunc_t fn = vtp->vt_func; \ 00138 vtp->vt_func = (vtfunc_t)NULL; \ 00139 vtp->vt_next->vt_prev = (void *)&vtlist; \ 00140 (&vtlist)->vt_next = vtp->vt_next; \ 00141 chSysUnlockFromIsr(); \ 00142 fn(vtp->vt_par); \ 00143 chSysLockFromIsr(); \ 00144 } \ 00145 } \ 00146 } 00147 00148 /** 00149 * @brief Returns @p TRUE if the specified timer is armed. 00150 * 00151 * @iclass 00152 */ 00153 #define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL) 00154 00155 /** 00156 * @brief Enables a virtual timer. 00157 * @note The associated function is invoked from interrupt context. 00158 * 00159 * @param[out] vtp the @p VirtualTimer structure pointer 00160 * @param[in] time the number of ticks before the operation timeouts, the 00161 * special values are handled as follow: 00162 * - @a TIME_INFINITE is allowed but interpreted as a 00163 * normal time specification. 00164 * - @a TIME_IMMEDIATE this value is not allowed. 00165 * . 00166 * @param[in] vtfunc the timer callback function. After invoking the 00167 * callback the timer is disabled and the structure can 00168 * be disposed or reused. 00169 * @param[in] par a parameter that will be passed to the callback 00170 * function 00171 * 00172 * @api 00173 */ 00174 #define chVTSet(vtp, time, vtfunc, par) { \ 00175 chSysLock(); \ 00176 chVTSetI(vtp, time, vtfunc, par); \ 00177 chSysUnlock(); \ 00178 } 00179 00180 /** 00181 * @brief Disables a Virtual Timer. 00182 * @note The timer is first checked and disabled only if armed. 00183 * 00184 * @param[in] vtp the @p VirtualTimer structure pointer 00185 * 00186 * @api 00187 */ 00188 #define chVTReset(vtp) { \ 00189 chSysLock(); \ 00190 if (chVTIsArmedI(vtp)) \ 00191 chVTResetI(vtp); \ 00192 chSysUnlock(); \ 00193 } 00194 00195 /** 00196 * @brief Current system time. 00197 * @details Returns the number of system ticks since the @p chSysInit() 00198 * invocation. 00199 * @note The counter can reach its maximum and then restart from zero. 00200 * @note This function is designed to work with the @p chThdSleepUntil(). 00201 * 00202 * @return The system time in ticks. 00203 * 00204 * @api 00205 */ 00206 #define chTimeNow() (vtlist.vt_systime) 00207 /** @} */ 00208 00209 extern VTList vtlist; 00210 00211 /* 00212 * Virtual Timers APIs. 00213 */ 00214 #ifdef __cplusplus 00215 extern "C" { 00216 #endif 00217 void _vt_init(void); 00218 void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par); 00219 void chVTResetI(VirtualTimer *vtp); 00220 bool_t chTimeIsWithin(systime_t start, systime_t end); 00221 #ifdef __cplusplus 00222 } 00223 #endif 00224 00225 #endif /* _CHVT_H_ */ 00226 00227 /** @} */