Zephyr OS Input Events: Assemble Coordinates Without Treating the Queue as a Frame

An input callback that receives an X coordinate does not necessarily have a new Y coordinate from the same report yet. When a device emits a logical update as several events, the consumer needs an explicit assembly rule. Queue emptiness is a scheduling observation, not a substitute for identifying the end of that device's update.

This article reviews Zephyr 4.4.0's input API and dispatch implementation. The coordinate example is hypothetical and assumes a producer contract that marks the final event of a logical update with sync. Confirm the selected input driver's actual sequence before adopting that contract.

Input assembly flow separates per-device pending axes, producer-defined sync boundary, continuity check and copied application-owned published state.
Original conceptual engineering diagram. Proposed review method, not a measured result.

Preserve device identity while accumulating fields

The tagged input header represents a single event with device, sync, type, code and value. A callback may be registered for one device or for all devices. An absolute coordinate is therefore an individual event, not an inherently complete coordinate pair.

Keep assembly state per producer. In a hypothetical two-axis device, an X update can replace the pending X field while the previous Y value remains available according to the producer's change-reporting rules. Publish the assembled state only at the agreed boundary. If the producer sends only changed values, demanding both axes anew on every report could reject valid updates; if it sends complete samples, silently reusing an old axis could conceal a missing event.

A callback registered for all devices must not combine one controller's X with another controller's Y. Device filtering is part of frame identity, alongside the event type and code. Unknown or irrelevant events should not accidentally terminate a pending update.

Sync does not turn several reports into an atomic queue operation

The tagged dispatch implementation creates and queues one event per input_report() call in threaded mode. The sync field travels with that event; the dispatcher invokes matching callbacks without assembling a coordinate frame. In synchronous mode it dispatches directly.

This leaves logical grouping to the producer and consumer agreement. If multiple contexts can report for the same logical producer, serialize their multi-event sequence or use another explicit design that preserves ownership. Merely placing a sync marker on the last event does not prevent an unrelated sequence from being interleaved between earlier events.

Keep the pending representation separate from the last published representation. A consumer should be able to explain which values are provisional and when they become one visible update. That distinction also helps when an application wants to discard an incomplete sequence after a device reset.

Handle an enqueue failure as a continuity problem

In threaded mode, input_report() can fail to enqueue an event. The implementation also changes a blocking timeout to K_NO_WAIT when called from the system workqueue. Check the result rather than assuming the entire logical update entered the input thread.

For a hypothetical X-then-Y sequence, losing X while delivering the final Y event could publish a mixed-generation position. Increasing queue capacity may reduce pressure, but it does not specify recovery. Decide how the producer communicates a fresh complete state or how the consumer detects and discards an incomplete update. Do not invent an automatic frame-loss notification that the inspected dispatcher does not provide.

If the device protocol supports a complete resample, that may provide a clean recovery point. Otherwise the design needs a documented limitation or an additional application-level continuity mechanism. The correct option depends on the actual device and the consequences of a stale coordinate.

Keep callback storage and execution context explicit

Copy the values needed after the callback returns into application-owned storage. In the inspected implementation, event objects are temporary dispatch storage, not an application-owned persistent record. Retaining the pointer for a later GUI operation therefore introduces a separate lifetime problem.

Test interleaved devices, unchanged-axis reports, an intentionally failed enqueue, and both relevant processing modes. Observe the assembled updates rather than only the raw event count. The integration is ready when every published position has a defined producer, boundary and continuity policy, and incomplete event sequences cannot masquerade as a coherent new frame.

Similar Posts

Leave a Reply

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