File tree Expand file tree Collapse file tree 2 files changed +38
-4
lines changed Expand file tree Collapse file tree 2 files changed +38
-4
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ use std::future::Future;
4
4
use tokio:: task:: spawn_blocking;
5
5
6
6
use super :: { jlink:: read_elf, Arch , DebugProbe , Target } ;
7
+ use crate :: utils:: retry_on_fail_with_delay;
7
8
8
9
pub struct RaspberryPiPico ;
9
10
@@ -67,9 +68,10 @@ impl DebugProbe for RaspberryPiPicoUsbDebugProbe {
67
68
68
69
/// Program and execute the specified ELF file by PICOBOOT protocol.
69
70
async fn program_and_run_by_picoboot ( exe : & std:: path:: Path ) -> Result < ( ) > {
70
- let ( picoboot_interface, loadable_code) =
71
- tokio:: join!( spawn_blocking( open_picoboot) , read_elf( exe) ) ;
72
- let picoboot_interface = picoboot_interface. unwrap ( ) ; // ignore `JoinError`
71
+ let picoboot_interface_async = retry_on_fail_with_delay ( || async {
72
+ spawn_blocking ( open_picoboot) . await . unwrap ( ) // ignore `JoinError`
73
+ } ) ;
74
+ let ( picoboot_interface, loadable_code) = tokio:: join!( picoboot_interface_async, read_elf( exe) ) ;
73
75
let PicobootInterface {
74
76
mut device_handle,
75
77
out_endpoint_i,
Original file line number Diff line number Diff line change 1
- use std:: { fmt, future:: Future } ;
1
+ use std:: { fmt, future:: Future , time:: Duration } ;
2
+ use tokio:: time:: delay_for;
2
3
3
4
pub struct CommaSeparatedNoSpace < T > ( pub T ) ;
4
5
impl < T > fmt:: Display for CommaSeparatedNoSpace < T >
82
83
}
83
84
}
84
85
}
86
+
87
+ pub async fn retry_on_fail_with_delay < R , T , E : std:: fmt:: Debug > (
88
+ mut f : impl FnMut ( ) -> R ,
89
+ ) -> Result < T , E >
90
+ where
91
+ R : Future < Output = Result < T , E > > ,
92
+ {
93
+ let mut count = 8u32 ;
94
+ loop {
95
+ match f ( ) . await {
96
+ Ok ( x) => return Ok ( x) ,
97
+ Err ( e) => {
98
+ log:: warn!( "Attempt failed: {:?}" , e) ;
99
+ count -= 1 ;
100
+ if count == 0 {
101
+ log:: warn!( "Retry limit reached" ) ;
102
+ return Err ( e) ;
103
+ } else {
104
+ let delay = ( 16 >> count) . max ( 1 ) ;
105
+ log:: warn!(
106
+ "Retrying in {} seconds... (remaining count = {:?})" ,
107
+ delay,
108
+ count
109
+ ) ;
110
+
111
+ delay_for ( Duration :: from_secs ( delay) ) . await ;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
You can’t perform that action at this time.
0 commit comments