        -:    0:Source:../../../os/rt/include/chvt.h
        -:    0:Programs:16
        -:    1:/*
        -:    2:    ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio.
        -:    3:
        -:    4:    This file is part of ChibiOS.
        -:    5:
        -:    6:    ChibiOS is free software; you can redistribute it and/or modify
        -:    7:    it under the terms of the GNU General Public License as published by
        -:    8:    the Free Software Foundation; either version 3 of the License, or
        -:    9:    (at your option) any later version.
        -:   10:
        -:   11:    ChibiOS is distributed in the hope that it will be useful,
        -:   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
        -:   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        -:   14:    GNU General Public License for more details.
        -:   15:
        -:   16:    You should have received a copy of the GNU General Public License
        -:   17:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
        -:   18:*/
        -:   19:
        -:   20:/**
        -:   21: * @file    chvt.h
        -:   22: * @brief   Time and Virtual Timers module macros and structures.
        -:   23: *
        -:   24: * @addtogroup time
        -:   25: * @{
        -:   26: */
        -:   27:
        -:   28:#ifndef CHVT_H
        -:   29:#define CHVT_H
        -:   30:
        -:   31:/*===========================================================================*/
        -:   32:/* Module constants.                                                         */
        -:   33:/*===========================================================================*/
        -:   34:
        -:   35:/**
        -:   36: * @name    Special time constants
        -:   37: * @{
        -:   38: */
        -:   39:/**
        -:   40: * @brief   Zero time specification for some functions with a timeout
        -:   41: *          specification.
        -:   42: * @note    Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
        -:   43: *          see the specific function documentation.
        -:   44: */
        -:   45:#define TIME_IMMEDIATE  ((systime_t)0)
        -:   46:
        -:   47:/**
        -:   48: * @brief   Infinite time specification for all functions with a timeout
        -:   49: *          specification.
        -:   50: * @note    Not all functions accept @p TIME_INFINITE as timeout parameter,
        -:   51: *          see the specific function documentation.
        -:   52: */
        -:   53:#define TIME_INFINITE   ((systime_t)-1)
        -:   54:
        -:   55:/**
        -:   56: * @brief   Maximum time constant.
        -:   57: */
        -:   58:#define TIME_MAXIMUM    ((systime_t)-2)
        -:   59:/** @} */
        -:   60:
        -:   61:/**
        -:   62: * @brief   Maximum unsigned integer.
        -:   63: */
        -:   64:#define __UINT_MAX      ((unsigned int)-1)
        -:   65:
        -:   66:/*===========================================================================*/
        -:   67:/* Module pre-compile time settings.                                         */
        -:   68:/*===========================================================================*/
        -:   69:
        -:   70:/*===========================================================================*/
        -:   71:/* Derived constants and error checks.                                       */
        -:   72:/*===========================================================================*/
        -:   73:
        -:   74:#if (CH_CFG_ST_RESOLUTION != 16) && (CH_CFG_ST_RESOLUTION != 32)
        -:   75:#error "invalid CH_CFG_ST_RESOLUTION specified, must be 16 or 32"
        -:   76:#endif
        -:   77:
        -:   78:#if CH_CFG_ST_FREQUENCY <= 0
        -:   79:#error "invalid CH_CFG_ST_FREQUENCY specified, must be greater than zero"
        -:   80:#endif
        -:   81:
        -:   82:#if (CH_CFG_ST_TIMEDELTA < 0) || (CH_CFG_ST_TIMEDELTA == 1)
        -:   83:#error "invalid CH_CFG_ST_TIMEDELTA specified, must "                       \
        -:   84:       "be zero or greater than one"
        -:   85:#endif
        -:   86:
        -:   87:#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_CFG_TIME_QUANTUM > 0)
        -:   88:#error "CH_CFG_TIME_QUANTUM not supported in tickless mode"
        -:   89:#endif
        -:   90:
        -:   91:#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_DBG_THREADS_PROFILING == TRUE)
        -:   92:#error "CH_DBG_THREADS_PROFILING not supported in tickless mode"
        -:   93:#endif
        -:   94:
        -:   95:/*===========================================================================*/
        -:   96:/* Module data structures and types.                                         */
        -:   97:/*===========================================================================*/
        -:   98:
        -:   99:/*===========================================================================*/
        -:  100:/* Module macros.                                                            */
        -:  101:/*===========================================================================*/
        -:  102:
        -:  103:/**
        -:  104: * @name    Fast time conversion utilities
        -:  105: * @{
        -:  106: */
        -:  107:/**
        -:  108: * @brief   Seconds to system ticks.
        -:  109: * @details Converts from seconds to system ticks number.
        -:  110: * @note    The result is rounded upward to the next tick boundary.
        -:  111: * @note    Use of this macro for large values is not secure because
        -:  112: *          integer overflows, make sure your value can be correctly
        -:  113: *          converted.
        -:  114: *
        -:  115: * @param[in] sec       number of seconds
        -:  116: * @return              The number of ticks.
        -:  117: *
        -:  118: * @api
        -:  119: */
        -:  120:#define S2ST(sec)                                                           \
        -:  121:  ((systime_t)((uint32_t)(sec) * (uint32_t)CH_CFG_ST_FREQUENCY))
        -:  122:
        -:  123:/**
        -:  124: * @brief   Milliseconds to system ticks.
        -:  125: * @details Converts from milliseconds to system ticks number.
        -:  126: * @note    The result is rounded upward to the next tick boundary.
        -:  127: * @note    Use of this macro for large values is not secure because
        -:  128: *          integer overflows, make sure your value can be correctly
        -:  129: *          converted.
        -:  130: *
        -:  131: * @param[in] msec      number of milliseconds
        -:  132: * @return              The number of ticks.
        -:  133: *
        -:  134: * @api
        -:  135: */
        -:  136:#define MS2ST(msec)                                                         \
        -:  137:  ((systime_t)(((((uint32_t)(msec)) *                                       \
        -:  138:                 ((uint32_t)CH_CFG_ST_FREQUENCY)) + 999UL) / 1000UL))
        -:  139:
        -:  140:/**
        -:  141: * @brief   Microseconds to system ticks.
        -:  142: * @details Converts from microseconds to system ticks number.
        -:  143: * @note    The result is rounded upward to the next tick boundary.
        -:  144: * @note    Use of this macro for large values is not secure because
        -:  145: *          integer overflows, make sure your value can be correctly
        -:  146: *          converted.
        -:  147: *
        -:  148: * @param[in] usec      number of microseconds
        -:  149: * @return              The number of ticks.
        -:  150: *
        -:  151: * @api
        -:  152: */
        -:  153:#define US2ST(usec)                                                         \
        -:  154:  ((systime_t)(((((uint32_t)(usec)) *                                       \
        -:  155:                 ((uint32_t)CH_CFG_ST_FREQUENCY)) + 999999UL) / 1000000UL))
        -:  156:
        -:  157:/**
        -:  158: * @brief   System ticks to seconds.
        -:  159: * @details Converts from system ticks number to seconds.
        -:  160: * @note    The result is rounded up to the next second boundary.
        -:  161: * @note    Use of this macro for large values is not secure because
        -:  162: *          integer overflows, make sure your value can be correctly
        -:  163: *          converted.
        -:  164: *
        -:  165: * @param[in] n         number of system ticks
        -:  166: * @return              The number of seconds.
        -:  167: *
        -:  168: * @api
        -:  169: */
        -:  170:#define ST2S(n) (((n) + CH_CFG_ST_FREQUENCY - 1UL) / CH_CFG_ST_FREQUENCY)
        -:  171:
        -:  172:/**
        -:  173: * @brief   System ticks to milliseconds.
        -:  174: * @details Converts from system ticks number to milliseconds.
        -:  175: * @note    The result is rounded up to the next millisecond boundary.
        -:  176: * @note    Use of this macro for large values is not secure because
        -:  177: *          integer overflows, make sure your value can be correctly
        -:  178: *          converted.
        -:  179: *
        -:  180: * @param[in] n         number of system ticks
        -:  181: * @return              The number of milliseconds.
        -:  182: *
        -:  183: * @api
        -:  184: */
        -:  185:#define ST2MS(n) (((n) * 1000UL + CH_CFG_ST_FREQUENCY - 1UL) /              \
        -:  186:                  CH_CFG_ST_FREQUENCY)
        -:  187:
        -:  188:/**
        -:  189: * @brief   System ticks to microseconds.
        -:  190: * @details Converts from system ticks number to microseconds.
        -:  191: * @note    The result is rounded up to the next microsecond boundary.
        -:  192: * @note    Use of this macro for large values is not secure because
        -:  193: *          integer overflows, make sure your value can be correctly
        -:  194: *          converted.
        -:  195: *
        -:  196: * @param[in] n         number of system ticks
        -:  197: * @return              The number of microseconds.
        -:  198: *
        -:  199: * @api
        -:  200: */
        -:  201:#define ST2US(n) (((n) * 1000000UL + CH_CFG_ST_FREQUENCY - 1UL) /           \
        -:  202:                  CH_CFG_ST_FREQUENCY)
        -:  203:/** @} */
        -:  204:
        -:  205:/*===========================================================================*/
        -:  206:/* External declarations.                                                    */
        -:  207:/*===========================================================================*/
        -:  208:
        -:  209:/*
        -:  210: * Virtual Timers APIs.
        -:  211: */
        -:  212:#ifdef __cplusplus
        -:  213:extern "C" {
        -:  214:#endif
        -:  215:  void _vt_init(void);
        -:  216:  void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
        -:  217:                  vtfunc_t vtfunc, void *par);
        -:  218:  void chVTDoResetI(virtual_timer_t *vtp);
        -:  219:#ifdef __cplusplus
        -:  220:}
        -:  221:#endif
        -:  222:
        -:  223:/*===========================================================================*/
        -:  224:/* Module inline functions.                                                  */
        -:  225:/*===========================================================================*/
        -:  226:
        -:  227:/**
        -:  228: * @name    Secure time conversion utilities
        -:  229: * @{
        -:  230: */
        -:  231:/**
        -:  232: * @brief   Seconds to system ticks.
        -:  233: * @details Converts from seconds to system ticks number.
        -:  234: * @note    The result is rounded upward to the next tick boundary.
        -:  235: * @note    This function uses a 64 bits internal representation,
        -:  236: *          use with non-constant parameters can lead to inefficient
        -:  237: *          code because 64 bits arithmetic would be used at runtime.
        -:  238: *
        -:  239: * @param[in] sec       number of seconds
        -:  240: * @return              The number of ticks.
        -:  241: *
        -:  242: * @api
        -:  243: */
        -:  244:static inline systime_t LL_S2ST(unsigned int sec) {
        -:  245:  uint64_t ticks = (uint64_t)sec * (uint64_t)CH_CFG_ST_FREQUENCY;
        -:  246:
        -:  247:  chDbgAssert(ticks <= (uint64_t)TIME_MAXIMUM, "conversion overflow");
        -:  248:
        -:  249:  return (systime_t)ticks;
        -:  250:}
        -:  251:
        -:  252:/**
        -:  253: * @brief   Milliseconds to system ticks.
        -:  254: * @details Converts from milliseconds to system ticks number.
        -:  255: * @note    The result is rounded upward to the next tick boundary.
        -:  256: * @note    This function uses a 64 bits internal representation,
        -:  257: *          use with non-constant parameters can lead to inefficient
        -:  258: *          code because 64 bits arithmetic would be used at runtime.
        -:  259: *
        -:  260: * @param[in] msec      number of milliseconds
        -:  261: * @return              The number of ticks.
        -:  262: *
        -:  263: * @api
        -:  264: */
        -:  265:static inline systime_t LL_MS2ST(unsigned int msec) {
        -:  266:  uint64_t ticks = (((uint64_t)msec * (uint64_t)CH_CFG_ST_FREQUENCY) + 999ULL)
        -:  267:                   / 1000ULL;
        -:  268:
        -:  269:  chDbgAssert(ticks <= (uint64_t)TIME_MAXIMUM, "conversion overflow");
        -:  270:
        -:  271:  return (systime_t)ticks;
        -:  272:}
        -:  273:
        -:  274:/**
        -:  275: * @brief   Microseconds to system ticks.
        -:  276: * @details Converts from microseconds to system ticks number.
        -:  277: * @note    The result is rounded upward to the next tick boundary.
        -:  278: * @note    This function uses a 64 bits internal representation,
        -:  279: *          use with non-constant parameters can lead to inefficient
        -:  280: *          code because 64 bits arithmetic would be used at runtime.
        -:  281: *
        -:  282: * @param[in] usec      number of microseconds
        -:  283: * @return              The number of ticks.
        -:  284: *
        -:  285: * @api
        -:  286: */
        -:  287:static inline systime_t LL_US2ST(unsigned int usec) {
        -:  288:  uint64_t ticks = (((uint64_t)usec * (uint64_t)CH_CFG_ST_FREQUENCY) + 999999ULL)
        -:  289:                   / 1000000ULL;
        -:  290:
        -:  291:  chDbgAssert(ticks <= (uint64_t)TIME_MAXIMUM, "conversion overflow");
        -:  292:
        -:  293:  return (systime_t)ticks;
        -:  294:}
        -:  295:
        -:  296:/**
        -:  297: * @brief   System ticks to seconds.
        -:  298: * @details Converts from system ticks number to seconds.
        -:  299: * @note    The result is rounded up to the next second boundary.
        -:  300: * @note    This function uses a 64 bits internal representation,
        -:  301: *          use with non-constant parameters can lead to inefficient
        -:  302: *          code because 64 bits arithmetic would be used at runtime.
        -:  303: *
        -:  304: * @param[in] n         number of system ticks
        -:  305: * @return              The number of seconds.
        -:  306: *
        -:  307: * @api
        -:  308: */
        -:  309:static inline unsigned int LL_ST2S(systime_t n) {
        -:  310:  uint64_t sec = ((uint64_t)n + (uint64_t)CH_CFG_ST_FREQUENCY - 1ULL)
        -:  311:                 / (uint64_t)CH_CFG_ST_FREQUENCY;
        -:  312:
        -:  313:  chDbgAssert(sec < (uint64_t)__UINT_MAX, "conversion overflow");
        -:  314:
        -:  315:  return (unsigned int)sec;
        -:  316:}
        -:  317:
        -:  318:/**
        -:  319: * @brief   System ticks to milliseconds.
        -:  320: * @details Converts from system ticks number to milliseconds.
        -:  321: * @note    The result is rounded up to the next millisecond boundary.
        -:  322: * @note    This function uses a 64 bits internal representation,
        -:  323: *          use with non-constant parameters can lead to inefficient
        -:  324: *          code because 64 bits arithmetic would be used at runtime.
        -:  325: *
        -:  326: * @param[in] n         number of system ticks
        -:  327: * @return              The number of milliseconds.
        -:  328: *
        -:  329: * @api
        -:  330: */
        -:  331:static inline unsigned int LL_ST2MS(systime_t n) {
        -:  332:  uint64_t msec = (((uint64_t)n * 1000ULL) + (uint64_t)CH_CFG_ST_FREQUENCY - 1ULL)
        -:  333:                   / (uint64_t)CH_CFG_ST_FREQUENCY;
        -:  334:
        -:  335:  chDbgAssert(msec < (uint64_t)__UINT_MAX, "conversion overflow");
        -:  336:
        -:  337:  return (unsigned int)msec;
        -:  338:}
        -:  339:
        -:  340:/**
        -:  341: * @brief   System ticks to microseconds.
        -:  342: * @details Converts from system ticks number to microseconds.
        -:  343: * @note    The result is rounded up to the next microsecond boundary.
        -:  344: * @note    This function uses a 64 bits internal representation,
        -:  345: *          use with non-constant parameters can lead to inefficient
        -:  346: *          code because 64 bits arithmetic would be used at runtime.
        -:  347: *
        -:  348: * @param[in] n         number of system ticks
        -:  349: * @return              The number of microseconds.
        -:  350: *
        -:  351: * @api
        -:  352: */
        -:  353:static inline unsigned int LL_ST2US(systime_t n) {
        -:  354:  uint64_t usec = (((uint64_t)n * 1000000ULL) + (uint64_t)CH_CFG_ST_FREQUENCY - 1ULL)
        -:  355:                   / (uint64_t)CH_CFG_ST_FREQUENCY;
        -:  356:
        -:  357:  chDbgAssert(usec < (uint64_t)__UINT_MAX, "conversion overflow");
        -:  358:
        -:  359:  return (unsigned int)usec;
        -:  360:}
        -:  361:/** @} */
        -:  362:
        -:  363:/**
        -:  364: * @brief   Initializes a @p virtual_timer_t object.
        -:  365: * @note    Initializing a timer object is not strictly required because
        -:  366: *          the function @p chVTSetI() initializes the object too. This
        -:  367: *          function is only useful if you need to perform a @p chVTIsArmed()
        -:  368: *          check before calling @p chVTSetI().
        -:  369: *
        -:  370: * @param[out] vtp      the @p virtual_timer_t structure pointer
        -:  371: *
        -:  372: * @init
        -:  373: */
        -:  374:static inline void chVTObjectInit(virtual_timer_t *vtp) {
        -:  375:
        -:  376:  vtp->func = NULL;
        -:  377:}
        -:  378:
        -:  379:/**
        -:  380: * @brief   Current system time.
        -:  381: * @details Returns the number of system ticks since the @p chSysInit()
        -:  382: *          invocation.
        -:  383: * @note    The counter can reach its maximum and then restart from zero.
        -:  384: * @note    This function can be called from any context but its atomicity
        -:  385: *          is not guaranteed on architectures whose word size is less than
        -:  386: *          @p systime_t size.
        -:  387: *
        -:  388: * @return              The system time in ticks.
        -:  389: *
        -:  390: * @xclass
        -:  391: */
function chVTGetSystemTimeX called 1 returned 100% blocks executed 100%
        1:  392:static inline systime_t chVTGetSystemTimeX(void) {
        -:  393:
        -:  394:#if CH_CFG_ST_TIMEDELTA == 0
        1:  395:  return ch.vtlist.systime;
unconditional  0 taken 100%
        -:  396:#else /* CH_CFG_ST_TIMEDELTA > 0 */
        -:  397:  return port_timer_get_time();
        -:  398:#endif /* CH_CFG_ST_TIMEDELTA > 0 */
        -:  399:}
        -:  400:
        -:  401:/**
        -:  402: * @brief   Current system time.
        -:  403: * @details Returns the number of system ticks since the @p chSysInit()
        -:  404: *          invocation.
        -:  405: * @note    The counter can reach its maximum and then restart from zero.
        -:  406: *
        -:  407: * @return              The system time in ticks.
        -:  408: *
        -:  409: * @api
        -:  410: */
        -:  411:static inline systime_t chVTGetSystemTime(void) {
        -:  412:  systime_t systime;
        -:  413:
        -:  414:  chSysLock();
        -:  415:  systime = chVTGetSystemTimeX();
        -:  416:  chSysUnlock();
        -:  417:
        -:  418:  return systime;
        -:  419:}
        -:  420:
        -:  421:/**
        -:  422: * @brief   Returns the elapsed time since the specified start time.
        -:  423: *
        -:  424: * @param[in] start     start time
        -:  425: * @return              The elapsed time.
        -:  426: *
        -:  427: * @xclass
        -:  428: */
        -:  429:static inline systime_t chVTTimeElapsedSinceX(systime_t start) {
        -:  430:
        -:  431:  return chVTGetSystemTimeX() - start;
        -:  432:}
        -:  433:
        -:  434:/**
        -:  435: * @brief   Checks if the specified time is within the specified time window.
        -:  436: * @note    When start==end then the function returns always true because the
        -:  437: *          whole time range is specified.
        -:  438: * @note    This function can be called from any context.
        -:  439: *
        -:  440: * @param[in] time      the time to be verified
        -:  441: * @param[in] start     the start of the time window (inclusive)
        -:  442: * @param[in] end       the end of the time window (non inclusive)
        -:  443: * @retval true         current time within the specified time window.
        -:  444: * @retval false        current time not within the specified time window.
        -:  445: *
        -:  446: * @xclass
        -:  447: */
function chVTIsTimeWithinX called 0 returned 0% blocks executed 0%
    #####:  448:static inline bool chVTIsTimeWithinX(systime_t time,
        -:  449:                                     systime_t start,
        -:  450:                                     systime_t end) {
        -:  451:
    #####:  452:  return (bool)((systime_t)(time - start) < (systime_t)(end - start));
unconditional  0 never executed
        -:  453:}
        -:  454:
        -:  455:/**
        -:  456: * @brief   Checks if the current system time is within the specified time
        -:  457: *          window.
        -:  458: * @note    When start==end then the function returns always true because the
        -:  459: *          whole time range is specified.
        -:  460: *
        -:  461: * @param[in] start     the start of the time window (inclusive)
        -:  462: * @param[in] end       the end of the time window (non inclusive)
        -:  463: * @retval true         current time within the specified time window.
        -:  464: * @retval false        current time not within the specified time window.
        -:  465: *
        -:  466: * @xclass
        -:  467: */
        -:  468:static inline bool chVTIsSystemTimeWithinX(systime_t start, systime_t end) {
        -:  469:
        -:  470:  return chVTIsTimeWithinX(chVTGetSystemTimeX(), start, end);
        -:  471:}
        -:  472:
        -:  473:/**
        -:  474: * @brief   Checks if the current system time is within the specified time
        -:  475: *          window.
        -:  476: * @note    When start==end then the function returns always true because the
        -:  477: *          whole time range is specified.
        -:  478: *
        -:  479: * @param[in] start     the start of the time window (inclusive)
        -:  480: * @param[in] end       the end of the time window (non inclusive)
        -:  481: * @retval true         current time within the specified time window.
        -:  482: * @retval false        current time not within the specified time window.
        -:  483: *
        -:  484: * @api
        -:  485: */
        -:  486:static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
        -:  487:
        -:  488:  return chVTIsTimeWithinX(chVTGetSystemTime(), start, end);
        -:  489:}
        -:  490:
        -:  491:/**
        -:  492: * @brief   Returns the time interval until the next timer event.
        -:  493: * @note    The return value is not perfectly accurate and can report values
        -:  494: *          in excess of @p CH_CFG_ST_TIMEDELTA ticks.
        -:  495: * @note    The interval returned by this function is only meaningful if
        -:  496: *          more timers are not added to the list until the returned time.
        -:  497: *
        -:  498: * @param[out] timep    pointer to a variable that will contain the time
        -:  499: *                      interval until the next timer elapses. This pointer
        -:  500: *                      can be @p NULL if the information is not required.
        -:  501: * @return              The time, in ticks, until next time event.
        -:  502: * @retval false        if the timers list is empty.
        -:  503: * @retval true         if the timers list contains at least one timer.
        -:  504: *
        -:  505: * @iclass
        -:  506: */
        -:  507:static inline bool chVTGetTimersStateI(systime_t *timep) {
        -:  508:
        -:  509:  chDbgCheckClassI();
        -:  510:
        -:  511:  if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.next) {
        -:  512:    return false;
        -:  513:  }
        -:  514:
        -:  515:  if (timep != NULL) {
        -:  516:#if CH_CFG_ST_TIMEDELTA == 0
        -:  517:    *timep = ch.vtlist.next->delta;
        -:  518:#else
        -:  519:    *timep = ch.vtlist.lasttime + ch.vtlist.next->delta +
        -:  520:             CH_CFG_ST_TIMEDELTA - chVTGetSystemTimeX();
        -:  521:#endif
        -:  522:  }
        -:  523:
        -:  524:  return true;
        -:  525:}
        -:  526:
        -:  527:/**
        -:  528: * @brief   Returns @p true if the specified timer is armed.
        -:  529: * @pre     The timer must have been initialized using @p chVTObjectInit()
        -:  530: *          or @p chVTDoSetI().
        -:  531: *
        -:  532: * @param[in] vtp       the @p virtual_timer_t structure pointer
        -:  533: * @return              true if the timer is armed.
        -:  534: *
        -:  535: * @iclass
        -:  536: */
function chVTIsArmedI called 54 returned 100% blocks executed 100%
       54:  537:static inline bool chVTIsArmedI(virtual_timer_t *vtp) {
        -:  538:
        -:  539:  chDbgCheckClassI();
        -:  540:
       54:  541:  return (bool)(vtp->func != NULL);
unconditional  0 taken 100%
        -:  542:}
        -:  543:
        -:  544:/**
        -:  545: * @brief   Returns @p true if the specified timer is armed.
        -:  546: * @pre     The timer must have been initialized using @p chVTObjectInit()
        -:  547: *          or @p chVTDoSetI().
        -:  548: *
        -:  549: * @param[in] vtp       the @p virtual_timer_t structure pointer
        -:  550: * @return              true if the timer is armed.
        -:  551: *
        -:  552: * @api
        -:  553: */
        -:  554:static inline bool chVTIsArmed(virtual_timer_t *vtp) {
        -:  555:  bool b;
        -:  556:
        -:  557:  chSysLock();
        -:  558:  b = chVTIsArmedI(vtp);
        -:  559:  chSysUnlock();
        -:  560:
        -:  561:  return b;
        -:  562:}
        -:  563:
        -:  564:/**
        -:  565: * @brief   Disables a Virtual Timer.
        -:  566: * @note    The timer is first checked and disabled only if armed.
        -:  567: * @pre     The timer must have been initialized using @p chVTObjectInit()
        -:  568: *          or @p chVTDoSetI().
        -:  569: *
        -:  570: * @param[in] vtp       the @p virtual_timer_t structure pointer
        -:  571: *
        -:  572: * @iclass
        -:  573: */
        -:  574:static inline void chVTResetI(virtual_timer_t *vtp) {
        -:  575:
        -:  576:  if (chVTIsArmedI(vtp)) {
        -:  577:    chVTDoResetI(vtp);
        -:  578:  }
        -:  579:}
        -:  580:
        -:  581:/**
        -:  582: * @brief   Disables a Virtual Timer.
        -:  583: * @note    The timer is first checked and disabled only if armed.
        -:  584: * @pre     The timer must have been initialized using @p chVTObjectInit()
        -:  585: *          or @p chVTDoSetI().
        -:  586: *
        -:  587: * @param[in] vtp       the @p virtual_timer_t structure pointer
        -:  588: *
        -:  589: * @api
        -:  590: */
        -:  591:static inline void chVTReset(virtual_timer_t *vtp) {
        -:  592:
        -:  593:  chSysLock();
        -:  594:  chVTResetI(vtp);
        -:  595:  chSysUnlock();
        -:  596:}
        -:  597:
        -:  598:/**
        -:  599: * @brief   Enables a virtual timer.
        -:  600: * @details If the virtual timer was already enabled then it is re-enabled
        -:  601: *          using the new parameters.
        -:  602: * @pre     The timer must have been initialized using @p chVTObjectInit()
        -:  603: *          or @p chVTDoSetI().
        -:  604: *
        -:  605: * @param[in] vtp       the @p virtual_timer_t structure pointer
        -:  606: * @param[in] delay     the number of ticks before the operation timeouts, the
        -:  607: *                      special values are handled as follow:
        -:  608: *                      - @a TIME_INFINITE is allowed but interpreted as a
        -:  609: *                        normal time specification.
        -:  610: *                      - @a TIME_IMMEDIATE this value is not allowed.
        -:  611: *                      .
        -:  612: * @param[in] vtfunc    the timer callback function. After invoking the
        -:  613: *                      callback the timer is disabled and the structure can
        -:  614: *                      be disposed or reused.
        -:  615: * @param[in] par       a parameter that will be passed to the callback
        -:  616: *                      function
        -:  617: *
        -:  618: * @iclass
        -:  619: */
        -:  620:static inline void chVTSetI(virtual_timer_t *vtp, systime_t delay,
        -:  621:                            vtfunc_t vtfunc, void *par) {
        -:  622:
        -:  623:  chVTResetI(vtp);
        -:  624:  chVTDoSetI(vtp, delay, vtfunc, par);
        -:  625:}
        -:  626:
        -:  627:/**
        -:  628: * @brief   Enables a virtual timer.
        -:  629: * @details If the virtual timer was already enabled then it is re-enabled
        -:  630: *          using the new parameters.
        -:  631: * @pre     The timer must have been initialized using @p chVTObjectInit()
        -:  632: *          or @p chVTDoSetI().
        -:  633: *
        -:  634: * @param[in] vtp       the @p virtual_timer_t structure pointer
        -:  635: * @param[in] delay     the number of ticks before the operation timeouts, the
        -:  636: *                      special values are handled as follow:
        -:  637: *                      - @a TIME_INFINITE is allowed but interpreted as a
        -:  638: *                        normal time specification.
        -:  639: *                      - @a TIME_IMMEDIATE this value is not allowed.
        -:  640: *                      .
        -:  641: * @param[in] vtfunc    the timer callback function. After invoking the
        -:  642: *                      callback the timer is disabled and the structure can
        -:  643: *                      be disposed or reused.
        -:  644: * @param[in] par       a parameter that will be passed to the callback
        -:  645: *                      function
        -:  646: *
        -:  647: * @api
        -:  648: */
        -:  649:static inline void chVTSet(virtual_timer_t *vtp, systime_t delay,
        -:  650:                           vtfunc_t vtfunc, void *par) {
        -:  651:
        -:  652:  chSysLock();
        -:  653:  chVTSetI(vtp, delay, vtfunc, par);
        -:  654:  chSysUnlock();
        -:  655:}
        -:  656:
        -:  657:/**
        -:  658: * @brief   Virtual timers ticker.
        -:  659: * @note    The system lock is released before entering the callback and
        -:  660: *          re-acquired immediately after. It is callback's responsibility
        -:  661: *          to acquire the lock if needed. This is done in order to reduce
        -:  662: *          interrupts jitter when many timers are in use.
        -:  663: *
        -:  664: * @iclass
        -:  665: */
function chVTDoTickI called 14592 returned 100% blocks executed 100%
    14592:  666:static inline void chVTDoTickI(void) {
        -:  667:
        -:  668:  chDbgCheckClassI();
        -:  669:
        -:  670:#if CH_CFG_ST_TIMEDELTA == 0
    14592:  671:  ch.vtlist.systime++;
    14592:  672:  if (&ch.vtlist != (virtual_timers_list_t *)ch.vtlist.next) {
branch  0 taken 31% (fallthrough)
branch  1 taken 69%
        -:  673:    /* The list is not empty, processing elements on top.*/
     4471:  674:    --ch.vtlist.next->delta;
     8996:  675:    while (ch.vtlist.next->delta == (systime_t)0) {
unconditional  0 taken 100%
branch  1 taken 1%
branch  2 taken 99% (fallthrough)
        -:  676:      virtual_timer_t *vtp;
        -:  677:      vtfunc_t fn;
        -:  678:
       54:  679:      vtp = ch.vtlist.next;
       54:  680:      fn = vtp->func;
       54:  681:      vtp->func = NULL;
       54:  682:      vtp->next->prev = (virtual_timer_t *)&ch.vtlist;
       54:  683:      ch.vtlist.next = vtp->next;
       54:  684:      chSysUnlockFromISR();
call    0 returned 100%
       54:  685:      fn(vtp->par);
call    0 returned 100%
       54:  686:      chSysLockFromISR();
call    0 returned 100%
unconditional  1 taken 100%
        -:  687:    }
        -:  688:  }
        -:  689:#else /* CH_CFG_ST_TIMEDELTA > 0 */
        -:  690:  virtual_timer_t *vtp;
        -:  691:  systime_t now, delta;
        -:  692:
        -:  693:  /* First timer to be processed.*/
        -:  694:  vtp = ch.vtlist.next;
        -:  695:  now = chVTGetSystemTimeX();
        -:  696:
        -:  697:  /* All timers within the time window are triggered and removed,
        -:  698:     note that the loop is stopped by the timers header having
        -:  699:     "ch.vtlist.vt_delta == (systime_t)-1" which is greater than
        -:  700:     all deltas.*/
        -:  701:  while (vtp->delta <= (systime_t)(now - ch.vtlist.lasttime)) {
        -:  702:    vtfunc_t fn;
        -:  703:
        -:  704:    /* The "last time" becomes this timer's expiration time.*/
        -:  705:    ch.vtlist.lasttime += vtp->delta;
        -:  706:
        -:  707:    vtp->next->prev = (virtual_timer_t *)&ch.vtlist;
        -:  708:    ch.vtlist.next = vtp->next;
        -:  709:    fn = vtp->func;
        -:  710:    vtp->func = NULL;
        -:  711:
        -:  712:    /* if the list becomes empty then the timer is stopped.*/
        -:  713:    if (ch.vtlist.next == (virtual_timer_t *)&ch.vtlist) {
        -:  714:      port_timer_stop_alarm();
        -:  715:    }
        -:  716:
        -:  717:    /* Leaving the system critical zone in order to execute the callback
        -:  718:       and in order to give a preemption chance to higher priority
        -:  719:       interrupts.*/
        -:  720:    chSysUnlockFromISR();
        -:  721:
        -:  722:    /* The callback is invoked outside the kernel critical zone.*/
        -:  723:    fn(vtp->par);
        -:  724:
        -:  725:    /* Re-entering the critical zone in order to continue the exploration
        -:  726:       of the list.*/
        -:  727:    chSysLockFromISR();
        -:  728:
        -:  729:    /* Next element in the list, the current time could have advanced so
        -:  730:       recalculating the time window.*/
        -:  731:    vtp = ch.vtlist.next;
        -:  732:    now = chVTGetSystemTimeX();
        -:  733:  }
        -:  734:
        -:  735:  /* if the list is empty, nothing else to do.*/
        -:  736:  if (ch.vtlist.next == (virtual_timer_t *)&ch.vtlist) {
        -:  737:    return;
        -:  738:  }
        -:  739:
        -:  740:  /* Recalculating the next alarm time.*/
        -:  741:  delta = ch.vtlist.lasttime + vtp->delta - now;
        -:  742:  if (delta < (systime_t)CH_CFG_ST_TIMEDELTA) {
        -:  743:    delta = (systime_t)CH_CFG_ST_TIMEDELTA;
        -:  744:  }
        -:  745:  port_timer_set_alarm(now + delta);
        -:  746:
        -:  747:  chDbgAssert((chVTGetSystemTimeX() - ch.vtlist.lasttime) <=
        -:  748:              (now + delta - ch.vtlist.lasttime),
        -:  749:              "exceeding delta");
        -:  750:#endif /* CH_CFG_ST_TIMEDELTA > 0 */
    14592:  751:}
        -:  752:
        -:  753:#endif /* CHVT_H */
        -:  754:
        -:  755:/** @} */
