Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions hil/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub async fn is_recovery_mode_detected() -> Result<bool> {
/// If `device` is `None`, will get the first available device.
#[tracing::instrument]
pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {
const DEFAULT_HOLDING_DELAY: u64 = 5;
const INBETWEEN_DELAY: u64 = 4;

fn make_ftdi(device: Option<FtdiId>) -> Result<FtdiGpio> {
let builder = FtdiGpio::builder();
let builder = match &device {
Expand All @@ -37,7 +40,12 @@ pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {

info!("Turning off");
let device_clone = device.cloned();
let ftdi = tokio::task::spawn_blocking(|| -> Result<_, color_eyre::Report> {
let recovery_state = if recovery {
OutputState::Low
} else {
OutputState::High
};
let ftdi = tokio::task::spawn_blocking(move || -> Result<_, color_eyre::Report> {
for d in FtdiGpio::list_devices().wrap_err("failed to list ftdi devices")? {
debug!(
"ftdi device: desc:{}, serial:{}, vid:{}, pid:{}",
Expand All @@ -46,18 +54,18 @@ pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {
}
let mut ftdi = make_ftdi(device_clone)?;
ftdi.set_pin(BUTTON_PIN, OutputState::Low)?;
ftdi.set_pin(RECOVERY_PIN, OutputState::High)?;
ftdi.set_pin(RECOVERY_PIN, recovery_state)?;
Ok(ftdi)
})
.await
.wrap_err("task panicked")??;
tokio::time::sleep(Duration::from_secs(10)).await;
tokio::time::sleep(Duration::from_secs(DEFAULT_HOLDING_DELAY)).await;

info!("Resetting FTDI");
tokio::task::spawn_blocking(move || ftdi.destroy())
.await
.wrap_err("task panicked")??;
tokio::time::sleep(Duration::from_secs(4)).await;
tokio::time::sleep(Duration::from_secs(INBETWEEN_DELAY)).await;

info!("Turning on");
let device_clone = device.cloned();
Expand All @@ -74,7 +82,7 @@ pub async fn reboot(recovery: bool, device: Option<&FtdiId>) -> Result<()> {
})
.await
.wrap_err("task panicked")??;
tokio::time::sleep(Duration::from_secs(4)).await;
tokio::time::sleep(Duration::from_secs(DEFAULT_HOLDING_DELAY)).await;

tokio::task::spawn_blocking(move || ftdi.destroy())
.await
Expand Down
26 changes: 25 additions & 1 deletion hil/src/commands/ota/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ pub struct Ota {
/// Serial port ID for boot log capture (alternative to --serial-path)
#[arg(long, group = "serial")]
serial_id: Option<String>,

/// Skip NTP time synchronization check before the first reboot (after wipe_overlays).
/// Time sync will still be checked after reboot and before starting the update.
#[arg(long, default_value = "false")]
skip_time_sync_before_reboot: bool,
}

#[derive(Debug, Clone, clap::ValueEnum)]
Expand All @@ -94,6 +99,13 @@ impl Ota {
let _start_time = Instant::now();
info!("Starting OTA update to version: {}", self.target_version);

if let Some(log_dir) = self.log_file.parent() {
tokio::fs::create_dir_all(log_dir).await.wrap_err_with(|| {
format!("Failed to create log directory: {}", log_dir.display())
})?;
info!("Log directory created/verified: {}", log_dir.display());
}

let session = self.connect_ssh().await.inspect_err(|e| {
println!("OTA_RESULT=FAILED");
println!("OTA_ERROR=SSH_CONNECTION_FAILED: {e}");
Expand All @@ -105,7 +117,19 @@ impl Ota {
system::wipe_overlays(&session).await.inspect_err(|e| {
error!("Failed to wipe overlays: {}", e);
})?;
info!("Overlays wiped successfully, rebooting device");
info!("Overlays wiped successfully");

if !self.skip_time_sync_before_reboot {
info!("Waiting for NTP time synchronization before reboot");
system::wait_for_time_sync(&session)
.await
.inspect_err(|e| {
error!("Failed to sync time before reboot: {}", e);
})?;
info!("NTP time synchronized, rebooting device");
} else {
info!("Skipping NTP time synchronization before reboot (--skip-time-sync-before-reboot flag set)");
}

system::reboot_orb(&session).await?;
info!("Reboot command sent to Orb device");
Expand Down
Loading
Loading