gonzui


Format: Advanced Search

mtkernel_3/kernel/tkernel/timer.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    micro T-Kernel 3.00.00
    4:  *
    5:  *    Copyright (C) 2006-2019 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.1.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2019/12/11.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: /*
   15:  *      timer.c
   16:  *      Timer Control
   17:  */
   18: 
   19: #include "kernel.h"
   20: #include "timer.h"
   21: #include "../sysdepend/sys_timer.h"
   22: 
   23: /*
   24:  * Current time (Software clock)
   25:  *      'current_time' shows the total operation time since
   26:  *      operating system Starts. 'real_time_ofs' shows difference
   27:  *      between the current time and the operating system clock
   28:  *      (current_time). Do not change 'current_time' when setting
   29:  *      time by 'set_tim()'. Set 'real_time_ofs' with the time        
   30:  *      difference between 'current_time' and setup time.
   31:  *      Therefore 'current_time' does not affect with time change
   32:  *      and it increases simply.
   33:  */
   34: Noinit(EXPORT LSYSTIM   knl_current_time);        /* System operation time */
   35: Noinit(EXPORT LSYSTIM   knl_real_time_ofs);       /* Actual time - System operation time */
   36: 
   37: /* 
   38:  * Timer event queue
   39:  */
   40: Noinit(EXPORT QUEUE     knl_timer_queue);
   41: 
   42: /*
   43:  * Start system timer
   44:  */
   45: EXPORT ER knl_timer_startup( void )
   46: {
   47:         knl_current_time = knl_real_time_ofs = uitoll(0);
   48:         QueInit(&knl_timer_queue);
   49: 
   50:         /* Start timer interrupt */
   51:         knl_start_hw_timer();
   52: 
   53:         return E_OK;
   54: }
   55: 
   56: #if USE_SHUTDOWN
   57: /*
   58:  * Stop system timer
   59:  */
   60: EXPORT void knl_timer_shutdown( void )
   61: {
   62:         knl_terminate_hw_timer();
   63: }
   64: #endif /* USE_SHUTDOWN */
   65: 
   66: 
   67: /*
   68:  * Insert timer event to timer event queue
   69:  */
   70: LOCAL void knl_enqueue_tmeb( TMEB *event )
   71: {
   72:         QUEUE  *q;
   73:         ABSTIM ofs = lltoul(knl_current_time) - ABSTIM_DIFF_MIN;
   74: 
   75:         for ( q = knl_timer_queue.next; q != &knl_timer_queue; q = q->next ) {
   76:                 if ( (ABSTIM)(event->time - ofs) < (ABSTIM)((((TMEB*)q)->time) - ofs) ) {
   77:                         break;
   78:                 }
   79:         }
   80:         QueInsert(&event->queue, q);
   81: }
   82: 
   83: /*
   84:  * Set timeout event
   85:  *      Register the timer event 'event' onto the timer queue to
   86:  *      start after the timeout 'tmout'. At timeout, start with the
   87:  *      argument 'arg' on the callback function 'callback'.
   88:  *      When 'tmout' is TMO_FEVR, do not register onto the timer
   89:  *      queue, but initialize queue area in case 'timer_delete' 
   90:  *      is called later.
   91:  *
   92:  *      "include/tk/typedef.h"
   93:  *      typedef      W            TMO;
   94:  *      typedef UW           RELTIM;
   95:  *      #define TMO_FEVR     (-1)
   96:  */
   97: EXPORT void knl_timer_insert( TMEB *event, TMO tmout, CBACK callback, void *arg )
   98: {
   99:         event->callback = callback;
  100:         event->arg = arg;
  101: 
  102:         if ( tmout == TMO_FEVR ) {
  103:                 QueInit(&event->queue);
  104:         } else {
  105:                 /* To guarantee longer wait time specified by 'tmout',
  106:                    add TIMER_PERIOD on wait time */
  107:                 event->time = lltoul(knl_current_time) + tmout + TIMER_PERIOD;
  108:                 knl_enqueue_tmeb(event);
  109:         }
  110: }
  111: 
  112: EXPORT void knl_timer_insert_reltim( TMEB *event, RELTIM tmout, CBACK callback, void *arg )
  113: {
  114:         event->callback = callback;
  115:         event->arg = arg;
  116: 
  117:         /* To guarantee longer wait time specified by 'tmout',
  118:            add TIMER_PERIOD on wait time */
  119:         event->time = lltoul(knl_current_time) + tmout + TIMER_PERIOD;
  120:         knl_enqueue_tmeb(event);
  121: }
  122: 
  123: /*
  124:  * Set time specified event
  125:  *      Register the timer event 'evt' onto the timer queue to start at the 
  126:  *      (absolute) time 'time'.
  127:  *      'time' is not an actual time. It is system operation time.
  128:  */
  129: EXPORT void knl_timer_insert_abs( TMEB *evt, ABSTIM time, CBACK cback, void *arg )
  130: {
  131:         evt->callback = cback;
  132:         evt->arg = arg;
  133:         evt->time = time;
  134:         knl_enqueue_tmeb(evt);
  135: }
  136: 
  137: /* ------------------------------------------------------------------------ */
  138: 
  139: /*
  140:  * System imer interrupt handler
  141:  *      This interrupt handler starts every TIMER_PERIOD millisecond 
  142:  *      interval by hardware timer. Update the software clock and start the 
  143:  *      timer event upon arriving at start time.
  144:  */
  145: 
  146: EXPORT void knl_timer_handler( void )
  147: {
  148:         TMEB   *event;
  149:         ABSTIM cur;
  150: 
  151:         knl_clear_hw_timer_interrupt();                /* Clear timer interrupt */
  152: 
  153:         BEGIN_CRITICAL_SECTION;
  154:         knl_current_time = ll_add(knl_current_time, uitoll(TIMER_PERIOD));
  155:         cur = lltoul(knl_current_time);
  156: 
  157: #if USE_DBGSPT && defined(USE_FUNC_TD_INF_TSK)
  158:         if ( knl_ctxtsk != NULL ) {
  159:                 /* Task at execution */
  160:                 if ( knl_ctxtsk->sysmode > 0 ) {
  161:                         knl_ctxtsk->stime += TIMER_PERIOD;
  162:                 } else {
  163:                         knl_ctxtsk->utime += TIMER_PERIOD;
  164:                 }
  165:         }
  166: #endif
  167: 
  168:         /* Execute event that passed occurring time. */
  169:         while ( !isQueEmpty(&knl_timer_queue) ) {
  170:                 event = (TMEB*)knl_timer_queue.next;
  171: 
  172:                 if ( !knl_abstim_reached(cur, event->time) ) {
  173:                         break;
  174:                 }
  175: 
  176:                 QueRemove(&event->queue);
  177:                 if ( event->callback != NULL ) {
  178:                         (*event->callback)(event->arg);
  179:                 }
  180:         }
  181: 
  182:         END_CRITICAL_SECTION;
  183: 
  184:         knl_end_of_hw_timer_interrupt();               /* Clear timer interrupt */
  185: }