Files
Jacob DahlandJulian Oes c9b9a7a3fd [BACKPORT 1.18] fix(cdcacm_autostart): gate MAVLink start on USB port readiness (#28250)
* fix(cdcacm_autostart): start MAVLink without holding the USB port (#28185)

* fix(cdcacm_autostart): start MAVLink without holding the USB port

SYS_USB_AUTO=2 opened /dev/ttyACM0 O_RDONLY and kept it for the life of
the link, then treated a successful mavlink spawn as permanent success.
If mavlink later failed its UART open retries and exited, the driver
stayed "connected" and never restarted — listen-first hosts (production
USB MAVLink benches) saw no heartbeats until a VBUS cycle.

Start mavlink without a probe open, track its PID and restart if it
dies while VBUS is present, close the autodetect fd before handing the
device to a protocol, and drop the unused legacy cdc_acm_check path.

Assisted-by: Grok:grok-4.5
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(cdcacm_autostart): initialise actuator_armed before the armed gate

copy() leaves the destination untouched when a topic has never been advertised,
so with commander not running `report` is whatever was on the stack. When that
garbage has armed set, run_state_machine() takes the "do not reconfigure USB
while flying" branch every cycle and never advances the state machine, so
MAVLink is never started on the USB CDC — on a vehicle that is definitionally
not flying, because commander is not running.

Seen on an ARK FMU v6X production test bench: a `commander stop` early in the
sequence leaves `listener actuator_armed` reporting "never published", and from
then on `mavlink status` shows no ttyACM instance at all while a host that opens
the port waits out its timeout against silence.

Zero-initialising restores the correct default for that case: not armed, so the
state machine runs.

* Update src/drivers/cdcacm_autostart/cdcacm_autostart.cpp

* Update src/drivers/cdcacm_autostart/cdcacm_autostart.cpp

* Update src/drivers/cdcacm_autostart/cdcacm_autostart.cpp

* Update src/drivers/cdcacm_autostart/cdcacm_autostart.cpp

---------

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
(cherry picked from commit f05739035e)

* fix(cdcacm_autostart): remove mavlink autostart magic (#28197)

* fix(cdcacm_autostart): remove mavlink autostart magic

I don't understand why we would have to try to autostart mavlink at 2
Hz. It should be started and stopped exactly once, if "it dies" out of
nowhere then that's a bug to look into and fix, not something to mask.

* fix(cdcacm_autostart): gate mavlink start on port readiness

CDC/ACM registers /dev/ttyACM0 as soon as sercon returns, but the serial
device starts out disconnected and open() returns -ENOTCONN until the host
has enumerated and issued SET_CONFIGURATION. Spawning mavlink before that
leaves its three open retries as the only guard: if the host is slow, or
never enumerates at all (power-only cable, or a carrier that drives VBUS
detect from a GPIO), mavlink exits and the state machine sits in connected
with nothing on the link until VBUS cycles.

Probe the port before spawning mavlink and keep retrying on the normal
500ms tick until it opens, then release the probe so nothing holds a second
open for the life of the link. This makes the assumption that mavlink does
not exit on its own true by construction, so no supervision is needed.

The 1s post-sercon delay is redundant now that the probe gates the start.

Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

---------

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
(cherry picked from commit 6c8d548db0)

---------

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Julian Oes <julian@oes.ch>
2026-08-14 22:44:17 -06:00
..