mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-10-23 06:12:25 +00:00
fix: run TCP interface connect on its own task (instant UI / screen wake)
The blocking WiFiClient.connect() ran on the main loop and stalled it for the lwIP default (~18.5s) when the host was unreachable -- including the DNS lookup -- freezing the UI, so the screen took ~10s to wake. The 2-arg connect() also ignored CONNECT_TIMEOUT_MS (that only bounds reads). Move only the blocking connect() to a dedicated FreeRTOS task. read/write/frame stay on the main loop exactly as before (unchanged low-latency data path -- the link/Resource timing is untouched). An atomic _conn_state hands _client ownership between the task (while CONNECTING) and the main loop (while CONNECTED) so they never touch the socket concurrently. Bound the connect via the 3-arg connect() and back off retries to 15s. tests/hardware: wait_for_tcp_link() matched "started", keying on interface startup rather than the actual connect. With the async connect that let the harness drive the announce before the link was up, so the device's announce was lost and the first direct message (bz2-probe) failed. Match "connected to". Verified on a T-Deck: screen wake instant (connect off the main loop); e2e smoke 5/5 including bz2-on-receive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
This commit is contained in:
1 parent
88ec8c2523
commit
988e42c52c
3 files changed
+139
-12
No files matched your search
@@ -7,6 +7,9 @@
|
||||
#ifdef ARDUINO
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <atomic>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
@@ -42,9 +45,10 @@ public:
|
||||
static const uint32_t BITRATE_GUESS = 10 * 1000 * 1000; // 10 Mbps
|
||||
static const uint32_t HW_MTU = 1064; // Match UDPInterface
|
||||
|
||||
// Reconnection parameters (match Python RNS)
|
||||
static const uint32_t RECONNECT_WAIT_MS = 5000; // 5 seconds between reconnect attempts
|
||||
static const uint32_t CONNECT_TIMEOUT_MS = 5000; // 5 second connection timeout
|
||||
// Reconnection parameters. connect() runs on tcp_task (off the main loop),
|
||||
// but still bound the timeout and back off so a dead host doesn't busy-retry.
|
||||
static const uint32_t RECONNECT_WAIT_MS = 15000; // 15s between reconnect attempts
|
||||
static const uint32_t CONNECT_TIMEOUT_MS = 3000; // 3s connect timeout (task-side)
|
||||
|
||||
// TCP keepalive parameters (match Python RNS)
|
||||
static const int TCP_KEEPIDLE_SEC = 5;
|
||||
@@ -78,6 +82,21 @@ private:
|
||||
void configure_socket();
|
||||
void handle_disconnect();
|
||||
|
||||
#ifdef ARDUINO
|
||||
// Only the blocking connect()/DNS runs on tcp_task so it can't stall the
|
||||
// main loop (which froze the UI). read/write/frame all stay on the main loop
|
||||
// (low latency, unchanged data path). _conn_state hands _client ownership
|
||||
// between the two so they never touch the socket concurrently:
|
||||
// DISCONNECTED -> CONNECTING (task owns _client) -> CONNECTED (main loop
|
||||
// owns _client); main loop flips CONNECTED -> DISCONNECTED on a drop.
|
||||
enum ConnState : uint8_t { DISCONNECTED = 0, CONNECTING = 1, CONNECTED = 2 };
|
||||
static void tcp_task(void* arg);
|
||||
void task_loop();
|
||||
TaskHandle_t _task_handle = nullptr;
|
||||
volatile bool _task_running = false;
|
||||
std::atomic<uint8_t> _conn_state{DISCONNECTED};
|
||||
#endif
|
||||
|
||||
// HDLC frame processing
|
||||
void process_incoming();
|
||||
void extract_and_process_frames();
|
||||
@@ -89,18 +108,26 @@ private:
|
||||
// Connection state
|
||||
bool _initiator = true;
|
||||
uint32_t _last_connect_attempt = 0;
|
||||
#ifdef ARDUINO
|
||||
std::atomic<bool> _reconnected{false}; // re-established after offline (task-set)
|
||||
#else
|
||||
bool _reconnected = false; // Set when connection re-established after being offline
|
||||
#endif
|
||||
uint32_t _last_data_received = 0; // Track last data receipt for stale connection detection
|
||||
static const uint32_t STALE_CONNECTION_MS = 120000; // Consider connection stale after 2 min no data
|
||||
|
||||
public:
|
||||
// Check and clear reconnection flag (for announcing after reconnect)
|
||||
bool check_reconnected() {
|
||||
#ifdef ARDUINO
|
||||
return _reconnected.exchange(false);
|
||||
#else
|
||||
if (_reconnected) {
|
||||
_reconnected = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Reference in new issue
Block a user