示例#1
0
rtems_status_code rtems_timer_delete(
  rtems_id id
)
{
  Timer_Control     *the_timer;
  Objects_Locations  location;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Objects_Close( &_Timer_Information, &the_timer->Object );
      (void) _Watchdog_Remove( &the_timer->Ticker );
      _Timer_Free( the_timer );
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#2
0
rtems_status_code rtems_timer_cancel(
  rtems_id id
)
{
  Timer_Control   *the_timer;
  Objects_Locations       location;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( !_Timer_Is_dormant_class( the_timer->the_class ) )
        (void) _Watchdog_Remove( &the_timer->Ticker );
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#3
0
文件: timerreset.c 项目: gedare/rtems
rtems_status_code rtems_timer_reset(
  rtems_id id
)
{
  Timer_Control    *the_timer;
  ISR_lock_Context  lock_context;

  the_timer = _Timer_Get( id, &lock_context );
  if ( the_timer != NULL ) {
    Per_CPU_Control   *cpu;
    rtems_status_code  status;

    cpu = _Timer_Acquire_critical( the_timer, &lock_context );

    if ( _Timer_Is_interval_class( the_timer->the_class ) ) {
      _Timer_Cancel( cpu, the_timer );
      _Watchdog_Insert(
        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
        &the_timer->Ticker,
        cpu->Watchdog.ticks + the_timer->initial
      );
      status = RTEMS_SUCCESSFUL;
    } else {
      status = RTEMS_NOT_DEFINED;
    }

    _Timer_Release( cpu, &lock_context );
    return status;
  }

  return RTEMS_INVALID_ID;
}
示例#4
0
rtems_status_code rtems_timer_get_information(
  rtems_id                 id,
  rtems_timer_information *the_info
)
{
  Timer_Control     *the_timer;
  Objects_Locations  location;
  ISR_lock_Context   lock_context;
  Per_CPU_Control   *cpu;

  if ( !the_info )
    return RTEMS_INVALID_ADDRESS;

  the_timer = _Timer_Get( id, &location, &lock_context );
  switch ( location ) {

    case OBJECTS_LOCAL:
      cpu = _Timer_Acquire_critical( the_timer, &lock_context );
      the_info->the_class  = the_timer->the_class;
      the_info->initial    = the_timer->initial;
      the_info->start_time = the_timer->start_time;
      the_info->stop_time  = the_timer->stop_time;
      _Timer_Release( cpu, &lock_context );
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#5
0
rtems_status_code rtems_timer_fire_after(
  rtems_id                           id,
  rtems_interval                     ticks,
  rtems_timer_service_routine_entry  routine,
  void                              *user_data
)
{
  Timer_Control      *the_timer;
  Objects_Locations   location;
  ISR_Level           level;

  if ( ticks == 0 )
    return RTEMS_INVALID_NUMBER;

  if ( !routine )
    return RTEMS_INVALID_ADDRESS;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Timer_Cancel( the_timer );

      _ISR_Disable( level );

        /*
         *  Check to see if the watchdog has just been inserted by a
         *  higher priority interrupt.  If so, abandon this insert.
         */

        if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
          _ISR_Enable( level );
          _Objects_Put( &the_timer->Object );
          return RTEMS_SUCCESSFUL;
        }

        /*
         *  OK.  Now we now the timer was not rescheduled by an interrupt
         *  so we can atomically initialize it as in use.
         */

        the_timer->the_class = TIMER_INTERVAL;
        _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
      _ISR_Enable( level );


      _Watchdog_Insert_ticks( &the_timer->Ticker, ticks );
      _Objects_Put( &the_timer->Object );
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#6
0
rtems_status_code rtems_timer_reset(
  rtems_id id
)
{
  Timer_Control     *the_timer;
  Objects_Locations  location;
  rtems_status_code  status = RTEMS_SUCCESSFUL;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( the_timer->the_class == TIMER_INTERVAL ) {
        _Watchdog_Remove( &the_timer->Ticker );
        _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
      } else if ( the_timer->the_class == TIMER_INTERVAL_ON_TASK ) {
        Timer_server_Control *timer_server = _Timer_server;

        /*
         *  There is no way for a timer to have this class unless
         *  it was scheduled as a server fire.  That requires that
         *  the Timer Server be initiated.  So this error cannot
         *  occur unless something is internally wrong.
         */
        #if defined(RTEMS_DEBUG)
          if ( !timer_server ) {
            _Thread_Enable_dispatch();
            return RTEMS_INCORRECT_STATE;
          }
        #endif
        _Watchdog_Remove( &the_timer->Ticker );
        (*timer_server->schedule_operation)( timer_server, the_timer );
      } else {
        /*
         *  Must be dormant or time of day timer (e.g. TIMER_DORMANT,
         *  TIMER_TIME_OF_DAY, or TIMER_TIME_OF_DAY_ON_TASK).  We
         *  can only reset active interval timers.
         */
        status = RTEMS_NOT_DEFINED;
      }
      _Thread_Enable_dispatch();
      return status;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
rtems_status_code rtems_timer_server_fire_when(
  rtems_id                           id,
  rtems_time_of_day                  *wall_time,
  rtems_timer_service_routine_entry  routine,
  void                              *user_data
)
{
  Timer_Control        *the_timer;
  Objects_Locations     location;
  rtems_interval        seconds;
  Timer_server_Control *timer_server = _Timer_server;

  if ( !timer_server )
    return RTEMS_INCORRECT_STATE;

  if ( !_TOD.is_set )
    return RTEMS_NOT_DEFINED;

  if ( !routine )
    return RTEMS_INVALID_ADDRESS;

  if ( !_TOD_Validate( wall_time ) )
    return RTEMS_INVALID_CLOCK;

  seconds = _TOD_To_seconds( wall_time );
  if ( seconds <= _TOD_Seconds_since_epoch() )
    return RTEMS_INVALID_CLOCK;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      (void) _Watchdog_Remove( &the_timer->Ticker );
      the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
      _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
      the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch();

      (*timer_server->schedule_operation)( timer_server, the_timer );

      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#8
0
rtems_status_code _Timer_Fire(
  rtems_id                           id,
  rtems_interval                     interval,
  rtems_timer_service_routine_entry  routine,
  void                              *user_data,
  Timer_Classes                      the_class,
  Watchdog_Service_routine_entry     adaptor
)
{
  Timer_Control    *the_timer;
  ISR_lock_Context  lock_context;

  the_timer = _Timer_Get( id, &lock_context );
  if ( the_timer != NULL ) {
    Per_CPU_Control *cpu;

    cpu = _Timer_Acquire_critical( the_timer, &lock_context );
    _Timer_Cancel( cpu, the_timer );
    _Watchdog_Initialize( &the_timer->Ticker, adaptor );
    the_timer->the_class = the_class;
    the_timer->routine = routine;
    the_timer->user_data = user_data;
    the_timer->initial = interval;
    the_timer->start_time = _Timer_Get_CPU_ticks( cpu );

    if ( _Timer_Is_interval_class( the_class ) ) {
      _Watchdog_Insert(
        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
        &the_timer->Ticker,
        cpu->Watchdog.ticks + interval
      );
    } else {
      _Watchdog_Insert(
        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ],
        &the_timer->Ticker,
        _Watchdog_Realtime_from_seconds( interval )
      );
    }

    _Timer_Release( cpu, &lock_context );
    return RTEMS_SUCCESSFUL;
  }

  return RTEMS_INVALID_ID;
}
rtems_status_code rtems_timer_server_fire_after(
  Objects_Id                         id,
  rtems_interval                     ticks,
  rtems_timer_service_routine_entry  routine,
  void                              *user_data
)
{
  Timer_Control        *the_timer;
  Objects_Locations     location;
  ISR_Level             level;

  if ( !_Timer_Server )
    return RTEMS_INCORRECT_STATE;

  if ( !routine )
    return RTEMS_INVALID_ADDRESS;

  if ( ticks == 0 )
    return RTEMS_INVALID_NUMBER;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {
    case OBJECTS_REMOTE:            /* should never return this */
      return RTEMS_INTERNAL_ERROR;

    case OBJECTS_ERROR:
      return RTEMS_INVALID_ID;

    case OBJECTS_LOCAL:
      (void) _Watchdog_Remove( &the_timer->Ticker );

      _ISR_Disable( level );

        /*
         *  Check to see if the watchdog has just been inserted by a
         *  higher priority interrupt.  If so, abandon this insert.
         */

        if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
          _ISR_Enable( level );
          _Thread_Enable_dispatch();
          return RTEMS_SUCCESSFUL;
        }

        /*
         *  OK.  Now we now the timer was not rescheduled by an interrupt
         *  so we can atomically initialize it as in use.
         */

        the_timer->the_class = TIMER_INTERVAL_ON_TASK;
        _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
        the_timer->Ticker.initial = ticks;
      _ISR_Enable( level );

      _Timer_Server_stop_ticks_timer();
      _Timer_Server_process_ticks_chain();
      _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
       _Timer_Server_reset_ticks_timer();

      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;
  }

  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
}