Skip to content

fbuild: standardize flash→monitor handoff timing as per-family HandoffTiming on BoardFamily #691

Closed

Description

@zackees

TL;DR

Deployer::post_deploy_recovery() (the hook landed via #605) lets each deploy backend define how to bring the device back into a monitorable state. But the timing — how long to sleep after reset before opening monitor, how long the boot-banner drain should be, how many re-enumeration retries — is currently hardcoded per-deployer and varies wildly between known-good configurations. As fbuild grows board coverage this drift becomes a real bug source.

The FastLED #3339 LPC bring-up confirmed:

  • LPC845-BRK: ~0.5 s settle after pyocd reset, then drain residual bytes for ~2 s.
  • ESP32 native USB CDC: ~0.2 s settle, no drain.
  • Estimated for RP2040 BOOTSEL → app re-enumerate: 1-2 s VCOM disappear, ~3 s reattach.

No single place captures the table. This issue requests one.

Proposed shape

Add per-family settings on BoardFamily (proposed in #687):

pub struct HandoffTiming {
    /// Sleep after reset before first byte is expected.
    pub post_reset_settle_ms: u32,
    /// How long to drain boot-banner / boot-up junk before bring-up RPC.
    pub boot_drain_ms: u32,
    /// How long to wait for the port to reappear after USB drop (CDC re-enum,
    /// 1200-bps-touch bootloader, BOOTSEL).
    pub port_reappear_timeout_ms: u32,
    /// Max retries on transient open failures during the reappear window.
    pub open_retry_count: u8,
}

impl BoardFamily {
    pub fn handoff_timing(&self) -> HandoffTiming {
        use BoardFamily::*;
        match self {
            Esp32NativeUsbCdc | Esp32ExternalUart => HandoffTiming {
                post_reset_settle_ms: 200, boot_drain_ms: 0,
                port_reappear_timeout_ms: 3000, open_retry_count: 5,
            },
            CdcAcmBridge { .. } => HandoffTiming {
                post_reset_settle_ms: 500, boot_drain_ms: 2000,
                port_reappear_timeout_ms: 3000, open_retry_count: 3,
            },
            Teensy | NativeUsbCdcReset1200Bps => HandoffTiming {
                post_reset_settle_ms: 100, boot_drain_ms: 500,
                port_reappear_timeout_ms: 5000, open_retry_count: 10,
            },
            ArduinoAutoReset => HandoffTiming {
                post_reset_settle_ms: 1500, boot_drain_ms: 0,
                port_reappear_timeout_ms: 0, open_retry_count: 1,
            },
        }
    }
}

Then post_deploy_recovery() consumes the settings instead of hardcoding numbers.

Acceptance criteria

  • HandoffTiming struct on BoardFamily (depends on #687 landing).
  • Each deployer (esp32_native, future LpcDeployer, etc.) reads the settings instead of inline magic numbers.
  • FastLED-side autoresearch's _run_bring_up_tests can adopt the same settings via an exported helper (avoids drift between fbuild and FastLED's Python sleep numbers).
  • Per-family table documented in the usb-cdc-control-line-matrix.md doc proposed in #689.

Refs

Filed from the audit fan-out on FastLED/FastLED#3339.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions