/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
    This file is part of ChibiOS/RT.
    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/
/**
 * @page article_timing Reliable timings using Threads
 * One common task is to have threads do something at regular, scheduled,
 * intervals.
 * An obvious solution is to write something like this:
 * @code
msg_t my_thread(void *param) {
  while (TRUE) {
    do_something();
    chThdSleepMilliseconds(1000);   // Fixed interval
  }
}
 * @endcode
 * This example works well assuming that the @p do_something() execution time
 * is well below the system tick period and that @p my_thread() is not
 * preempted by other threads that could insert long intervals.
 * If the above conditions are not satisfied you may have @p do_something()
 * executed at irregular intervals, as example:
 * T0...T0+1000...T0+2002...T0+3002...T0+4005...etc.
 * Also note that the error increases over time and this kind of behavior can
 * lead to anomalies really hard to debug.
 * 
A better solution
 * It is possible to rewrite the above code using absolute deadlines rather
 * than fixed intervals:
 * @code
msg_t my_thread(void *param) {
  systick_t time = chTimeNow();     // T0
  while (TRUE) {
    time += MS2ST(1000);            // Next deadline
    do_something();
    chThdSleepUntil(time);
  }
}
 * @endcode
 * Using this code @p do_something() will always be executed at an absolute
 * deadline time and the error will not accumulate over time regardless of
 * the execution time and delays inserted by other threads.
 * Note that this solution requires that the @p do_something() execution
 * time must not exceed the deadline or the thread would stay sleeping into
 * @p chThdSleepUntil().
 *
 * A different way
 * Another way to perform activities at regular intervals is the use of a
 * virtual timer. Virtual timers are able to generate callbacks at scheduled
 * intervals. Virtual timers are one shot timers so you need to restart them
 * from within the callback if you need a periodic timer like in this case.
 * @code
VirtualTimer vt;
void do_something(void *p) {
  chVTSetI(&vt, MS2ST(1000), do_something, p);      // Restarts the timer.
  // Periodic code here.
}
int main(int argc, char **argv) {
  chSysLock();
  chVTSetI(&vt, MS2ST(1000), do_something, NULL);   // Starts the timer.
  chSysUnlock();
  ...
}
 * @endcode
 * Note that the callback code is executed from within the I-Locked state (see
 * @ref system_states) so you can only execute I-Class APIs from there (see
 * @ref api_suffixes).
 * This solution has the advantage to not require a dedicated thread and
 * thus uses much less RAM but the periodic code must have a very short
 * execution time or it would degrade the overall system response time.
 */