ChibiOS/RT
2.5.1
chvt.h
Go to the documentation of this file.
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 /** @} */