gonzui


Format: Advanced Search

tkernel_2/kernel/tkernel/src/timer.cbare sourcepermlink (0.02 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by T-Engine Forum at 2014/01/18.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: 
   16: /*
   17:  *      timer.c (T-Kernel/OS)
   18:  *      Timer Control
   19:  */
   20: 
   21: #include "kernel.h"
   22: #include "timer.h"
   23: #include "task.h"
   24: #include "tkdev_timer.h"
   25: #include <sys/rominfo.h>
   26: 
   27: /*
   28:  * Timer interrupt interval (us)
   29:  */
   30: EXPORT RELTIM_U TIMER_PERIOD;
   31: 
   32: /*
   33:  * Current time (Software clock)
   34:  *      'current_time' shows the total operation time since
   35:  *      operating system Starts. 'real_time_ofs' shows difference
   36:  *      between the current time and the operating system clock
   37:  *      (current_time). Do not change 'current_time' when setting
   38:  *      time by 'set_tim()'. Set 'real_time_ofs' with the time       
   39:  *      difference between 'current_time' and setup time.
   40:  *      Therefore 'current_time' does not affect with time change
   41:  *      and it increases simply.
   42:  */
   43: EXPORT LSYSTIM  current_time;    /* System operation time */
   44: EXPORT LSYSTIM  real_time_ofs;   /* Actual time - System operation time */
   45: 
   46: /*
   47:  * Timer event queue
   48:  */
   49: LOCAL QUEUE     timer_queue;
   50: 
   51: /*
   52:  * Initialization of timer module
   53:  */
   54: EXPORT ER timer_initialize( void )
   55: {
   56:         INT    n, t[2];
   57: 
   58:         /* Get system information */
   59:         n = _tk_get_cfn(SCTAG_TTIMPERIOD, t, 2);
   60:         if ( n < 1 ) return E_SYS;
   61:         if ( n < 2 ) t[1] = 0;
   62:         TIMER_PERIOD = to_usec(t[0]) + t[1];
   63:         if ( TIMER_PERIOD < MIN_TIMER_PERIOD
   64:           || TIMER_PERIOD > MAX_TIMER_PERIOD ) {
   65:                 return E_SYS;
   66:         }
   67: 
   68:         current_time = real_time_ofs = ltoll(0);
   69:         QueInit(&timer_queue);
   70: 
   71:         /* Start timer interrupt */
   72:         start_hw_timer();
   73: 
   74:         return E_OK;
   75: }
   76: 
   77: /*
   78:  * Stop timer
   79:  */
   80: EXPORT void timer_shutdown( void )
   81: {
   82:         terminate_hw_timer();
   83: }
   84: 
   85: /*
   86:  * Obtain the time for correction
   87:  *      Obtain the time for correction used for setting timeout, etc.
   88:  *     (in microseconds).
   89:  *      This returns the elapsed time from the last timer interrupt.
   90:  */
   91: EXPORT RELTIM_U adjust_time( void )
   92: {
   93:         return get_hw_timer_usec();
   94: }
   95: 
   96: /*
   97:  * Insert timer event to timer event queue
   98:  */
   99: LOCAL void enqueue_tmeb( TMEB *event )
  100: {
  101:         QUEUE  *q;
  102: 
  103:         for ( q = timer_queue.next; q != &timer_queue; q = q->next ) {
  104:                 if ( ll_cmp(event->time, ((TMEB*)q)->time) < 0) {
  105:                         break;
  106:                 }
  107:         }
  108:         QueInsert(&event->queue, q);
  109: }
  110: 
  111: /*
  112:  * Set timeout event
  113:  *      Register the timer event 'event' onto the timer queue to
  114:  *      start after the timeout 'tmout'. At timeout, start with the
  115:  *      argument 'arg' on the callback function 'callback'.
  116:  *      When 'tmout' is TMO_FEVR, do not register onto the timer
  117:  *      queue, but initialize queue area in case 'timer_delete'
  118:  *      is called later.
  119:  *
  120:  *      "include/tk/typedef.h"
  121:  *      typedef      INT          TMO;
  122:  *      typedef UINT         RELTIM;
  123:  *      #define TMO_FEVR     (-1)
  124:  */
  125: EXPORT void timer_insert( TMEB *event, TMO_U tmout, CBACK callback, void *arg )
  126: {
  127:         event->callback = callback;
  128:         event->arg = arg;
  129: 
  130:         if ( tmout == TMO_FEVR ) {
  131:                 QueInit(&event->queue);
  132:         } else {
  133:                 /* To guarantee longer wait time specified by 'tmout',
  134:                    add adjust_time() on wait time */
  135:                 event->time = ll_add( ll_add(current_time, ltoll(tmout)),
  136:                                         uitoll(adjust_time()) );
  137:                 enqueue_tmeb(event);
  138:         }
  139: }
  140: 
  141: EXPORT void timer_insert_reltim( TMEB *event, RELTIM_U tmout, CBACK callback, void *arg )
  142: {
  143:         event->callback = callback;
  144:         event->arg = arg;
  145: 
  146:         /* To guarantee longer wait time specified by 'tmout',
  147:            add adjust_time() on wait time */
  148:         event->time = ll_add( ll_add(current_time, ultoll(tmout)),
  149:                                 uitoll(adjust_time()) );
  150:         enqueue_tmeb(event);
  151: }
  152: 
  153: /*
  154:  * Set time specified event
  155:  *      Register the timer event 'evt' onto the timer queue to start at the
  156:  *      (absolute) time 'time'.
  157:  *      'time' is not an actual time. It is system operation time.
  158:  */
  159: EXPORT void timer_insert_abs( TMEB *evt, LSYSTIM time, CBACK cback, void *arg )
  160: {
  161:         evt->callback = cback;
  162:         evt->arg = arg;
  163:         evt->time = time;
  164:         enqueue_tmeb(evt);
  165: }
  166: 
  167: /* ------------------------------------------------------------------------ */
  168: 
  169: /*
  170:  * Timer interrupt handler
  171:  *      Timer interrupt handler starts every TIMER_PERIOD microsecond
  172:  *      interval by hardware timer. Update the software clock and start the
  173:  *      timer event upon arriving at start time.
  174:  */
  175: EXPORT void timer_handler( void )
  176: {
  177:         TMEB   *event;
  178: 
  179:         clear_hw_timer_interrupt();            /* Clear timer interrupt */
  180: 
  181:         BEGIN_CRITICAL_SECTION;
  182:         current_time = ll_add(current_time, uitoll(TIMER_PERIOD));
  183: 
  184:         if ( ctxtsk != NULL ) {
  185:                 /* Task at execution */
  186:                 if ( ctxtsk->sysmode > 0 ) {
  187:                         ctxtsk->stime += TIMER_PERIOD;
  188:                 } else {
  189:                         ctxtsk->utime += TIMER_PERIOD;
  190:                 }
  191: 
  192:                 if ( schedtsk == ctxtsk ) {
  193:                         schedtsk = time_slice_schedule(ctxtsk);
  194:                         if ( schedtsk != ctxtsk ) {
  195:                                 dispatch_request();
  196:                         }
  197:                 }
  198:         }
  199: 
  200:         /* Execute event that passed occurring time. */
  201:         while ( !isQueEmpty(&timer_queue) ) {
  202:                 event = (TMEB*)timer_queue.next;
  203:                 if ( ll_cmp(event->time, current_time) > 0 ) {
  204:                         break;
  205:                 }
  206: 
  207:                 QueRemove(&event->queue);
  208:                 if ( event->callback != NULL ) {
  209:                         (*event->callback)(event->arg);
  210:                 }
  211:         }
  212: 
  213:         END_CRITICAL_SECTION;
  214: 
  215:         end_of_hw_timer_interrupt();           /* Clear timer interrupt */
  216: }