Feature/optimize tcp driver (EPROT-77) - #182
Open
Octaviarius wants to merge 5 commits into
Open
Conversation
Octaviarius
force-pushed
the
feature/optimize-tcp-driver
branch
from
August 4, 2026 06:09
950fa20 to
36b44d6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title
fix(tcp): reduce transaction latency and handle fragmented TCP frames
Summary
This PR reduces Modbus TCP transaction latency, removes the redundant
esp_eventloop from the TCP driver, and makes TCP frame reception work correctly when an
MBAP header or payload is split across multiple TCP segments.
The driver task remains responsible for serializing all connection and protocol
events. Events are now stored in a lightweight per-driver FreeRTOS queue, while
eventfdis used only to wake the task blocked inselect().Motivation
The previous implementation used both:
esp_eventqueue for event storage and dispatch;eventfdto wake the TCP task;esp_event_loop_run()call.This added queueing, copying, dispatch, and timeout overhead without providing
additional concurrency or isolation. It could also delay socket processing while
the event loop was running.
TCP receive handling also assumed that a single
recv()call returned an entirerequested block. TCP does not preserve message boundaries, so fragmented MBAP
headers and payloads could be treated as invalid frames or connection failures.
Changes
Event processing
esp_eventloop with a per-driver FreeRTOS event queue.eventfdonly as a wake-up source forselect().esp_eventcomponent dependency.callback parameters.
TCP receive path
MSG_DONTWAITafterselect()reports readiness.fragmented frame.
Socket handling
TCP_NODELAYusingsetsockopt()after a connection is established.TCP_NODELAYas a flag tosend().fd >= 0.socket readiness.
select()read set.FD_ISSET()witha negative socket descriptor.
Lifecycle
eventfdownership per driver instance.Performance observation
In a local Modbus TCP polling test with one outstanding transaction at a time:
These numbers are hardware- and application-specific and are included only as an
indication of the reduced scheduling overhead.
Validation
compiler and the project
-Werrorflags:port_tcp_driver.cport_tcp_master.cport_tcp_slave.cport_tcp_utils.cgit diff --checkpasses.A complete ESP-IDF application build and the upstream hardware test suite were
not run as part of this change.