Beispiel #1
0
static void _Timer_server_Reset_tod_system_watchdog(
  Timer_server_Control *ts
)
{
  ISR_Level level;

  _Timer_server_Stop_tod_system_watchdog( ts );

  _ISR_Disable( level );
  if ( !_Chain_Is_empty( &ts->TOD_watchdogs.Chain ) ) {
    Watchdog_Interval delta_interval =
      _Watchdog_First( &ts->TOD_watchdogs.Chain )->delta_interval;
    _ISR_Enable( level );

    /*
     *  The unit is SECONDS here.
     */
    _Watchdog_Insert_seconds(
      &ts->TOD_watchdogs.System_watchdog,
      delta_interval
    );
  } else {
    _ISR_Enable( level );
  }
}
Beispiel #2
0
rtems_status_code rtems_timer_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;

  if ( !_TOD_Is_set() )
    return RTEMS_NOT_DEFINED;

  if ( !_TOD_Validate( wall_time ) )
    return RTEMS_INVALID_CLOCK;

  if ( !routine )
    return RTEMS_INVALID_ADDRESS;

  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;
      _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
      _Watchdog_Insert_seconds(
         &the_timer->Ticker,
         seconds - _TOD_Seconds_since_epoch()
       );
      _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;
}
Beispiel #3
0
rtems_status_code rtems_task_wake_when(
  rtems_time_of_day *time_buffer
)
{
  Watchdog_Interval   seconds;

  if ( !_TOD_Is_set() )
    return RTEMS_NOT_DEFINED;

  if ( !time_buffer )
    return RTEMS_INVALID_ADDRESS;

  time_buffer->ticks = 0;

  if ( !_TOD_Validate( time_buffer ) )
    return RTEMS_INVALID_CLOCK;

  seconds = _TOD_To_seconds( time_buffer );

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

  _Thread_Disable_dispatch();
    _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
    _Watchdog_Initialize(
      &_Thread_Executing->Timer,
      _Thread_Delay_ended,
      _Thread_Executing->Object.id,
      NULL
    );
    _Watchdog_Insert_seconds(
      &_Thread_Executing->Timer,
      seconds - _TOD_Seconds_since_epoch()
    );
  _Thread_Enable_dispatch();
  return RTEMS_SUCCESSFUL;
}
int timer_settime(
  timer_t                  timerid,
  int                      flags,
  const struct itimerspec *value,
  struct itimerspec       *ovalue
)
{
  POSIX_Timer_Control *ptimer;
  Objects_Locations    location;
  boolean              activated;

  if ( value == NULL ) {
    rtems_set_errno_and_return_minus_one( EINVAL );
  }

  /* First, it verifies if the structure "value" is correct */
  if ( ( value->it_value.tv_nsec > TOD_NANOSECONDS_PER_SECOND ) ||
       ( value->it_value.tv_nsec < 0 ) ) {
    /* The number of nanoseconds is not correct */
    rtems_set_errno_and_return_minus_one( EINVAL );
  }
  
  /* XXX check for seconds in the past */

  if ( flags != TIMER_ABSTIME && flags != POSIX_TIMER_RELATIVE ) {
    rtems_set_errno_and_return_minus_one( EINVAL );
  }

  /* If the function reaches this point, then it will be necessary to do
   * something with the structure of times of the timer: to stop, start
   * or start it again
   */

  ptimer = _POSIX_Timer_Get( timerid, &location );
  switch ( location ) {
    case OBJECTS_REMOTE:
#if defined(RTEMS_MULTIPROCESSING)
      _Thread_Dispatch();
      return -1;
     rtems_set_errno_and_return_minus_one( EINVAL );
#endif

    case OBJECTS_ERROR:
      return -1;

    case OBJECTS_LOCAL:
      /* First, it verifies if the timer must be stopped */
      if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
         /* Stop the timer */
         (void) _Watchdog_Remove( &ptimer->Timer );
         /* The old data of the timer are returned */
         if ( ovalue )
           *ovalue = ptimer->timer_data;
         /* The new data are set */
         ptimer->timer_data = *value;
         /* Indicates that the timer is created and stopped */
         ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
         /* Returns with success */
        _Thread_Enable_dispatch();
        return 0;
       }

       /* absolute or relative? */
       switch (flags) {
         case TIMER_ABSTIME:

           /* The fire time is absolute: use "rtems_time_fire_when" */
           /* First, it converts from struct itimerspec to rtems_time_of_day */

           _Watchdog_Initialize(
             &ptimer->Timer, _POSIX_Timer_TSR, ptimer->Object.id, ptimer );

           _Watchdog_Insert_seconds(
              &ptimer->Timer,
              value->it_value.tv_sec - _TOD_Seconds_since_epoch
           );

           /* Returns the old ones in "ovalue" */
           if ( ovalue )
             *ovalue = ptimer->timer_data;
           ptimer->timer_data = *value;

           /* Indicate that the time is running */
           ptimer->state = POSIX_TIMER_STATE_CREATE_RUN;

           /* Stores the time in which the timer was started again */
           _TOD_Get( &ptimer->time );
           _Thread_Enable_dispatch();
           return 0;
           break;

         /* The fire time is relative: use "rtems_time_fire_after" */
         case POSIX_TIMER_RELATIVE:
           /* First, convert from seconds and nanoseconds to ticks */
           ptimer->ticks = _Timespec_To_ticks( &value->it_value );

           activated = _Watchdog_Insert_ticks_helper(
             &ptimer->Timer,
             ptimer->ticks,
             ptimer->Object.id,
             _POSIX_Timer_TSR,
             ptimer
           );
           if ( !activated ) {
             _Thread_Enable_dispatch();
             return 0;
           }

           /* The timer has been started and is running */
           /* return the old ones in "ovalue" */
           if ( ovalue )
             *ovalue = ptimer->timer_data;
           ptimer->timer_data = *value;

           /* Indicate that the time is running */
           ptimer->state = POSIX_TIMER_STATE_CREATE_RUN;
           _TOD_Get( &ptimer->time );
            _Thread_Enable_dispatch();
           return 0;
      }
      _Thread_Enable_dispatch();
      rtems_set_errno_and_return_minus_one( EINVAL );
  }
  return -1;   /* unreached - only to remove warnings */
}