3131from ardupilot_methodic_configurator .annotate_params import Par
3232from ardupilot_methodic_configurator .argparse_check_range import CheckRange
3333from ardupilot_methodic_configurator .backend_flightcontroller_info import BackendFlightcontrollerInfo
34- from ardupilot_methodic_configurator .backend_mavftp import MAVFTP
34+ from ardupilot_methodic_configurator .backend_mavftp import MAVFTP , MAVFTPSettings
3535
3636# pylint: disable=too-many-lines
3737
@@ -596,21 +596,82 @@ def __download_params_via_mavlink(
596596 break
597597 return parameters
598598
599+ def _create_robust_mavftp_settings (self ) -> MAVFTPSettings :
600+ """
601+ Create robust MAVFTP settings optimized for STM32 F4 controllers under workload.
602+
603+ Returns:
604+ MAVFTPSettings: Configured settings with increased timeouts and reduced burst sizes
605+
606+ """
607+ return MAVFTPSettings (
608+ [
609+ ("debug" , int , 0 ),
610+ ("pkt_loss_tx" , int , 0 ),
611+ ("pkt_loss_rx" , int , 0 ),
612+ ("max_backlog" , int , 3 ), # Reduced backlog for better reliability
613+ ("burst_read_size" , int , 60 ), # Smaller burst size for stability
614+ ("write_size" , int , 60 ),
615+ ("write_qsize" , int , 3 ),
616+ ("idle_detection_time" , float , 8.0 ), # Increased for heavy workload scenarios
617+ ("read_retry_time" , float , 3.0 ), # Increased retry time
618+ ("retry_time" , float , 2.0 ), # Increased retry time
619+ ]
620+ )
621+
599622 def download_params_via_mavftp (
600623 self , progress_callback : Union [None , Callable [[int , int ], None ]] = None
601624 ) -> tuple [dict [str , float ], dict [str , "Par" ]]:
602625 if self .master is None :
603626 return {}, {}
604- mavftp = MAVFTP (self .master , target_system = self .master .target_system , target_component = self .master .target_component )
627+
628+ # Create more robust MAVFTP settings for parameter download
629+ # STM32 F4 controllers under workload need longer timeouts
630+ mavftp_settings = self ._create_robust_mavftp_settings ()
631+
632+ mavftp = MAVFTP (
633+ self .master ,
634+ target_system = self .master .target_system ,
635+ target_component = self .master .target_component ,
636+ settings = mavftp_settings ,
637+ )
605638
606639 def get_params_progress_callback (completion : float ) -> None :
607640 if progress_callback is not None and completion is not None :
608641 progress_callback (int (completion * 100 ), 100 )
609642
610643 complete_param_filename = "complete.param"
611644 default_param_filename = "00_default.param"
612- mavftp .cmd_getparams ([complete_param_filename , default_param_filename ], progress_callback = get_params_progress_callback )
613- ret = mavftp .process_ftp_reply ("getparams" , timeout = 10 )
645+
646+ # Retry logic for increased robustness with STM32 F4 controllers under workload
647+ max_retries = 3
648+ base_timeout = 15
649+
650+ for attempt in range (max_retries ):
651+ try :
652+ mavftp .cmd_getparams (
653+ [complete_param_filename , default_param_filename ], progress_callback = get_params_progress_callback
654+ )
655+ # Progressive timeout increase for each retry attempt
656+ timeout = base_timeout * (2 ** attempt ) # 15s, 30s, 60s
657+ logging_info (_ ("Attempt %d/%d: Requesting parameters with %ds timeout" ), attempt + 1 , max_retries , timeout )
658+ ret = mavftp .process_ftp_reply ("getparams" , timeout = timeout )
659+
660+ if ret .error_code == 0 :
661+ break # Success, exit retry loop
662+
663+ if attempt < max_retries - 1 : # Don't sleep after last attempt
664+ sleep_time = 2 ** attempt # 1s, 2s, 4s exponential backoff
665+ logging_warning (_ ("Parameter download attempt %d failed, retrying in %ds..." ), attempt + 1 , sleep_time )
666+ time_sleep (sleep_time )
667+ else :
668+ logging_error (_ ("All %d parameter download attempts failed" ), max_retries )
669+
670+ except Exception as e :
671+ logging_error (_ ("Exception during parameter download attempt %d: %s" ), attempt + 1 , str (e ))
672+ if attempt < max_retries - 1 :
673+ sleep_time = 2 ** attempt
674+ time_sleep (sleep_time )
614675 pdict = {}
615676 # add a file sync operation to ensure the file is completely written
616677 time_sleep (0.3 )
@@ -1077,14 +1138,23 @@ def upload_file(
10771138 """Upload a file to the flight controller."""
10781139 if self .master is None :
10791140 return False
1080- mavftp = MAVFTP (self .master , target_system = self .master .target_system , target_component = self .master .target_component )
1141+
1142+ # Use robust MAVFTP settings for better reliability with STM32 F4 controllers
1143+ mavftp_settings = self ._create_robust_mavftp_settings ()
1144+ mavftp = MAVFTP (
1145+ self .master ,
1146+ target_system = self .master .target_system ,
1147+ target_component = self .master .target_component ,
1148+ settings = mavftp_settings ,
1149+ )
10811150
10821151 def put_progress_callback (completion : float ) -> None :
10831152 if progress_callback is not None and completion is not None :
10841153 progress_callback (int (completion * 100 ), 100 )
10851154
10861155 mavftp .cmd_put ([local_filename , remote_filename ], progress_callback = put_progress_callback )
1087- ret = mavftp .process_ftp_reply ("CreateFile" , timeout = 10 )
1156+ # Increased timeout for better reliability
1157+ ret = mavftp .process_ftp_reply ("CreateFile" , timeout = 20 )
10881158 if ret .error_code != 0 :
10891159 ret .display_message ()
10901160 return ret .error_code == 0
@@ -1104,7 +1174,14 @@ def download_last_flight_log(
11041174 logging_error (error_msg )
11051175 return False
11061176
1107- mavftp = MAVFTP (self .master , target_system = self .master .target_system , target_component = self .master .target_component )
1177+ # Use robust MAVFTP settings for better reliability with STM32 F4 controllers
1178+ mavftp_settings = self ._create_robust_mavftp_settings ()
1179+ mavftp = MAVFTP (
1180+ self .master ,
1181+ target_system = self .master .target_system ,
1182+ target_component = self .master .target_component ,
1183+ settings = mavftp_settings ,
1184+ )
11081185
11091186 def get_progress_callback (completion : float ) -> None :
11101187 if progress_callback is not None and completion is not None :
@@ -1193,7 +1270,7 @@ def _get_log_number_by_scanning(self, mavftp: MAVFTP) -> Union[int, None]:
11931270 # Test if this log file exists
11941271 temp_test_file = f"temp_test_{ mid } .tmp"
11951272 mavftp .cmd_get ([remote_filename , temp_test_file ])
1196- ret = mavftp .process_ftp_reply ("OpenFileRO" , timeout = 5 ) # Must be > idle_detection_time (3.7s)
1273+ ret = mavftp .process_ftp_reply ("OpenFileRO" , timeout = 2 ) # Short timeout for existence check
11971274
11981275 # Clean up the temp file if it was created
11991276 if os .path .exists (temp_test_file ):
0 commit comments