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 ); } }
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; }
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 */ }