Zephyr OS USB CDC ACM: Keep Waiting for a Terminal Out of Product Startup

A board can expose a USB serial function and still appear to stop during startup because application code waits for DTR. That wait can be useful in an interactive demonstration, where the developer wants to see the first message. In a headless product, it can accidentally make the main function depend on a host opening a terminal.

The concrete example here is Zephyr 4.4.0's CDC ACM echo sample using the newer USB device stack. The proposed startup architecture is an application recommendation. No host compatibility test or USB trace is claimed.

CDC ACM startup flow separates device readiness and USB enablement from DTR and optional diagnostic session readiness.
Original conceptual engineering diagram. Proposed review method, not a measured result.

Locate the wait after USB enablement

The tagged CDC ACM sample enables USB support, initializes its ring buffer, and then waits on a DTR semaphore with K_FOREVER. Its control-line-state notification reads DTR and gives that semaphore when asserted. Only after the wait does main install the UART interrupt callback and enable receive interrupts.

This sequence explains why “USB enabled” and “echo application ready” are different observations in that sample. If code copied from the example places other initialization after the wait, those actions inherit its dependency. The issue is not proved to be an enumeration failure merely because the application has stopped progressing.

Instrument the startup milestones separately: device readiness, stack enable result, host configuration if observed, control-line change, and application receive readiness. Use an independent diagnostic path where possible. Otherwise the only channel intended to explain the wait may itself depend on satisfying it.

Decide which functions actually need a terminal

In a hypothetical environmental controller, sensing and local control should usually not depend on whether a maintenance terminal is open. Move terminal-specific readiness into its own state machine while letting independently safe product functions start through their normal checks.

An interactive service tool may deliberately require DTR before sending its greeting. A headless deployment may instead keep diagnostics optional. These are product decisions; deleting the wait without defining buffering and connection behavior merely exchanges one implicit assumption for another.

If a bounded wait is chosen, define what follows timeout. Continuing normal operation, entering a service mode, or recording that no maintenance session was present are different policies. Do not describe a timeout as proof that the USB host or cable failed: the host may simply not have opened the serial function in the expected way.

Do not block the notification path that advances state

The tagged USB device API documents message callback execution in the system workqueue when deferred mode is enabled, or in the USB device stack thread otherwise. It cautions against blocking or disrupting stack handling in the latter mode.

Keep notification handling small and move application waiting to an appropriate context. Waiting inside a notification handler for a later USB notification can create a dependency that prevents the very progress being awaited. Treat callback context as part of the integration, not as an ordinary background thread chosen by the application.

Also distinguish the sample's initial semaphore release from a complete session-lifecycle design. A product that depends on host readiness needs explicit handling for later control-line changes, disconnects and reconnects. A startup gate consumed once does not itself implement those transitions.

Specify what happens to diagnostics without a reader

Decide whether logs are dropped, buffered within a fixed bound, or sent through another configured backend when no usable terminal session exists. Avoid unbounded accumulation and avoid allowing optional diagnostics to stall time-sensitive product work.

Test power-up with no cable, a connected host without an open terminal, a terminal opened later, and a terminal closed during operation. Record product readiness separately from diagnostic availability. If the product requires host interaction, state that requirement clearly instead of presenting headless startup as supported.

The useful result is a startup path whose dependencies are intentional. DTR can remain a valid signal for an interactive serial session while no longer acting as an unnoticed prerequisite for unrelated device functions.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *