rtems_status_code _Timer_Fire_when( rtems_id id, const rtems_time_of_day *wall_time, rtems_timer_service_routine_entry routine, void *user_data, Timer_Classes the_class, Watchdog_Service_routine_entry adaptor ) { rtems_interval seconds; 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; return _Timer_Fire( id, seconds, routine, user_data, the_class, adaptor ); }
rtems_status_code rtems_clock_get_tod( rtems_time_of_day *time_buffer ) { rtems_time_of_day *tmbuf = time_buffer; struct tm time; struct timeval now; if ( !time_buffer ) return RTEMS_INVALID_ADDRESS; if ( !_TOD_Is_set() ) return RTEMS_NOT_DEFINED; /* Obtain the current time */ _TOD_Get_timeval( &now ); /* Split it into a closer format */ gmtime_r( &now.tv_sec, &time ); /* Now adjust it to the RTEMS format */ tmbuf->year = time.tm_year + 1900; tmbuf->month = time.tm_mon + 1; tmbuf->day = time.tm_mday; tmbuf->hour = time.tm_hour; tmbuf->minute = time.tm_min; tmbuf->second = time.tm_sec; tmbuf->ticks = now.tv_usec / rtems_configuration_get_microseconds_per_tick(); return RTEMS_SUCCESSFUL; }
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 ); _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_clock_get_tod_timeval( struct timeval *time ) { if ( !time ) return RTEMS_INVALID_ADDRESS; if ( !_TOD_Is_set() ) return RTEMS_NOT_DEFINED; _TOD_Get_timeval( time ); return RTEMS_SUCCESSFUL; }
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; }