/** @details -# Get the sim_mode -# Reset the real-time clock reference -# If sim_mode is Run -# Call start_realtime to start the real time clock -# Else if sim_mode is Freeze -# Call freeze init to set the sleep timer to freeze mode. */ int Trick::RealtimeSync::restart(long long ref_time) { SIM_MODE sim_mode = exec_get_mode() ; rt_clock->clock_reset(ref_time) ; if ( sim_mode == Run ) { start_realtime(exec_get_software_frame() , ref_time) ; } else if ( sim_mode == Freeze ) { freeze_init(exec_get_freeze_frame()) ; } return 0 ; }
/** * @relates Trick::RealtimeSync * @copydoc Trick::RealtimeSync::start_realtime * C wrapper for Trick::RealtimeSync::start_realtime */ extern "C" int real_time_restart(long long ref_time ) { if ( the_rts != NULL ) { return the_rts->start_realtime(exec_get_software_frame() , ref_time) ; } return(0) ; }
/** @details -# If real-time is not active: -# If real-time synchronization has been enabled: -# Set the active flag to true. -# Start real-time setting the real-time clock to the current simulation time. -# exit end of frame routine -# If real-time is active: -# If real-time synchronization has been disabled: -# Set the active flag to false. -# Get the current real-time. -# Calculate the real-time taken for the last frame of execution. -# if the frame has overrun -# Increment the number of consecutive overruns -# If the maximum number of consecutive overrun frames has been reached or the maximum single overrun time has been exceeded -# If the freeze/terminate action was set -# set the freeze_terminate flag -# freeze the simulation -# Else terminate the simulation -# Stop the sleep timer. -# Else the frame has underrun -# Reset the number of consecutive overruns to 0. -# Pause for the sleep timer to expire -# Spin for the real-time clock to match the simulation time -# Reset the sleep timer for the next frame -# Save the current real-time as the start of the frame reference */ int Trick::RealtimeSync::rt_monitor(long long sim_time_tics) { long long curr_clock_time ; char buf[512]; /* determine if the state of real-time has changed this frame */ if ( ! active ) { if ( enable_flag ) { active = true ; enable_flag = false ; start_realtime(exec_get_software_frame() , sim_time_tics) ; } if ( disable_flag ) { disable_flag = false ; } return(0) ; } if ( enable_flag ) { enable_flag = false ; } if ( disable_flag ) { active = false ; disable_flag = false ; } /* calculate the current underrun/overrun */ curr_clock_time = rt_clock->clock_time() ; frame_overrun_time = 0 ; frame_sched_time = curr_clock_time - last_clock_time ; frame_overrun_time = curr_clock_time - sim_time_tics ; /* If the wall clock time is greater than the sim time an overrun occurred. */ if (curr_clock_time > sim_time_tics) { /* Update the overrun counter and current overrun time */ frame_overrun_cnt++; total_overrun++; /* If the number overruns surpass the maximum allowed freeze or shutdown. */ if (frame_overrun_cnt >= rt_max_overrun_cnt || frame_overrun_time >= rt_max_overrun_time_tics) { /* If the rt_overrun_freeze flag is set, enter freeze mode else terminate the simulation. */ if (rt_overrun_freeze == true) { freeze_shutdown = true ; message_publish(MSG_ERROR, "\nMaximum overrun condition exceeded:\n" "consecutive overruns/allowed overruns: %d/%d\n" "total overrun time/allowed time: %f/%g\n" "Entering Freeze-Shutdown Mode\n" , frame_overrun_cnt, rt_max_overrun_cnt, (double)(frame_overrun_time/tics_per_sec), rt_max_overrun_time); exec_freeze() ; } else { sprintf(buf, "\nMaximum overrun condition exceeded:\n" "consecutive overruns/allowed overruns: %d/%d\n" "total overrun time/allowed time: %f/%g\n", frame_overrun_cnt, rt_max_overrun_cnt, (double)(frame_overrun_time/tics_per_sec), rt_max_overrun_time); exec_terminate_with_return(-1 , __FILE__ , __LINE__ , buf); } } /* stop the sleep timer in an overrun condition */ sleep_timer->stop() ; /* Call clock_spin to allow interrupt driven clocks to service their interrupts */ curr_clock_time = rt_clock->clock_spin(sim_time_tics) ; } else { /* Else an underrun condition occurred. */ /* Reset consecutive overrun counter frame_overrun_cnt */ frame_overrun_cnt = 0; /* pause for the timer to signal the end of frame */ sleep_timer->pause() ; /* Spin to make sure that we are at the top of the frame */ curr_clock_time = rt_clock->clock_spin(sim_time_tics) ; /* If the timer requires to be reset at the end of each frame, reset it here. */ sleep_timer->reset(exec_get_software_frame() / rt_clock->get_rt_clock_ratio()) ; } /* Set the next frame overrun/underrun reference time to the current time */ last_clock_time = curr_clock_time ; return(0) ; }