mirror of
https://github.com/agessaman/MeshCore.git
synced 2026-08-28 02:54:05 +00:00
Refactor MQTTBridge to utilize FreeRTOS for improved task management and responsiveness
- Moved MQTT processing to a dedicated FreeRTOS task on Core 0, enhancing non-blocking behavior. - Implemented a FreeRTOS queue for thread-safe packet handling, replacing the previous circular buffer approach. - Updated WiFi initialization and connection management to occur within the FreeRTOS task, improving overall system responsiveness. - Enhanced logging and error handling for MQTT connections and packet processing. - Cached broker and analyzer server statuses to reduce redundant checks and improve efficiency.
This commit is contained in:
@@ -1174,11 +1174,11 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
|
||||
|
||||
void MyMesh::loop() {
|
||||
// Check radio FIRST to ensure we don't miss incoming packets
|
||||
// MQTT processing can take time, so we prioritize radio reception
|
||||
// MQTT processing runs in a separate FreeRTOS task on Core 0, so we don't call bridge.loop() here
|
||||
mesh::Mesh::loop();
|
||||
|
||||
#ifdef WITH_BRIDGE
|
||||
bridge.loop();
|
||||
// bridge.loop() is now handled by FreeRTOS task on Core 0 - no need to call it here
|
||||
#endif
|
||||
|
||||
if (next_flood_advert && millisHasNowPassed(next_flood_advert)) {
|
||||
|
||||
@@ -898,7 +898,7 @@ void MyMesh::loop() {
|
||||
// MQTT processing can take time, so we prioritize radio reception
|
||||
mesh::Mesh::loop();
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
bridge.loop();
|
||||
// bridge.loop() is now handled by FreeRTOS task on Core 0 - no need to call it here
|
||||
#endif
|
||||
|
||||
if (millisHasNowPassed(next_push) && acl.getNumClients() > 0) {
|
||||
|
||||
+651
-140
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,13 @@
|
||||
#include <Timezone.h>
|
||||
#include "helpers/JWTHelper.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/queue.h>
|
||||
#include <freertos/semphr.h>
|
||||
#endif
|
||||
|
||||
#if defined(MQTT_DEBUG) && defined(ARDUINO)
|
||||
#include <Arduino.h>
|
||||
// USB CDC-aware debug macros: only print if Serial is ready (non-blocking check)
|
||||
@@ -96,10 +103,19 @@ private:
|
||||
};
|
||||
|
||||
static const int MAX_QUEUE_SIZE = 10;
|
||||
|
||||
// FreeRTOS queue for thread-safe packet queuing
|
||||
#ifdef ESP_PLATFORM
|
||||
QueueHandle_t _packet_queue_handle;
|
||||
TaskHandle_t _mqtt_task_handle;
|
||||
SemaphoreHandle_t _raw_data_mutex; // Mutex for raw radio data
|
||||
#else
|
||||
// Fallback to circular buffer for non-ESP32 platforms
|
||||
QueuedPacket _packet_queue[MAX_QUEUE_SIZE];
|
||||
int _queue_head;
|
||||
int _queue_tail;
|
||||
int _queue_count;
|
||||
#endif
|
||||
int _queue_count; // Protected by queue operations or mutex
|
||||
|
||||
// NTP time sync
|
||||
WiFiUDP _ntp_udp;
|
||||
@@ -151,6 +167,10 @@ private:
|
||||
// Configuration validation state
|
||||
bool _config_valid;
|
||||
|
||||
// Cached broker connection status (updated in callbacks to avoid redundant checks)
|
||||
bool _cached_has_brokers;
|
||||
bool _cached_has_analyzer_servers;
|
||||
|
||||
// Throttle logging for disconnected broker messages
|
||||
unsigned long _last_no_broker_log;
|
||||
static const unsigned long NO_BROKER_LOG_INTERVAL = 30000; // Log every 30 seconds max
|
||||
@@ -172,6 +192,13 @@ private:
|
||||
void connectToBrokers();
|
||||
void processPacketQueue();
|
||||
bool publishStatus(); // Returns true if status was successfully published
|
||||
|
||||
// FreeRTOS task function (runs on Core 0)
|
||||
#ifdef ESP_PLATFORM
|
||||
static void mqttTask(void* parameter);
|
||||
void mqttTaskLoop(); // Main loop for MQTT task
|
||||
void initializeWiFiInTask(); // WiFi initialization moved to task
|
||||
#endif
|
||||
void publishPacket(mesh::Packet* packet, bool is_tx,
|
||||
const uint8_t* raw_data = nullptr, int raw_len = 0,
|
||||
float snr = 0.0f, float rssi = 0.0f);
|
||||
|
||||
@@ -103,7 +103,27 @@ int RadioLibWrapper::recvRaw(uint8_t* bytes, int sz) {
|
||||
if (len > sz) { len = sz; }
|
||||
int err = _radio->readData(bytes, len);
|
||||
if (err != RADIOLIB_ERR_NONE) {
|
||||
MESH_DEBUG_PRINTLN("RadioLibWrapper: error: readData(%d)", err);
|
||||
// Throttle error logging to avoid spam (CRC errors are common in noisy environments)
|
||||
static unsigned long last_crc_error_log = 0;
|
||||
static unsigned long crc_error_count = 0;
|
||||
unsigned long now = millis();
|
||||
crc_error_count++;
|
||||
|
||||
// Log every 10 seconds max, or on first error
|
||||
if (last_crc_error_log == 0 || (now - last_crc_error_log > 10000)) {
|
||||
MESH_DEBUG_PRINTLN("RadioLibWrapper: error: readData(%d) - %lu errors in last 10s", err, crc_error_count);
|
||||
last_crc_error_log = now;
|
||||
crc_error_count = 0;
|
||||
}
|
||||
|
||||
// For CRC mismatch errors (-7), reset radio state to prevent stuck conditions
|
||||
// Similar to CustomLR1110's handling of header errors
|
||||
if (err == -7) { // RADIOLIB_ERR_CRC_MISMATCH
|
||||
// Call standby() to reset radio to known-good state
|
||||
// This helps recover from false packet detections or corrupted state
|
||||
_radio->standby();
|
||||
}
|
||||
|
||||
len = 0;
|
||||
} else {
|
||||
// Serial.print(" readData() -> "); Serial.println(len);
|
||||
|
||||
Reference in New Issue
Block a user