Stabilità e memoria

Il firmware MS2-Pro implementa diversi meccanismi automatici per garantire stabilità operativa anche in condizioni di carico elevato (più servizi di rete attivi contemporaneamente, WiFi instabile, batteria bassa). Questa pagina spiega come funzionano e cosa fare in caso di problemi.

Contesto hardware

Il microcontrollore ESP32 del ricevitore MS2-Pro:

  • DRAM totale: ~320 KB
  • Heap disponibile a runtime: ~180-220 KB (dipende dai servizi attivi)
  • Nessuna PSRAM: tutta la memoria utente è interna al chip ESP32

Per confronto, ogni servizio di rete consuma:

  • WiFi stack: ~30-50 KB
  • SPP Classic + BTDM (Bluetooth Classico): ~50-60 KB — il più pesante perché include sia stack Bluedroid + profilo SPP che lo schedule Classic
  • BLE NUS (Bluetooth Low Energy con Nordic UART Service): ~20-25 KB — circa metà di SPP
  • WIFI-only (BT completamente scaricato via esp_bt_controller_mem_release): 0 KB per Bluetooth → libera ~30-50 KB rispetto a SPP/BLE
  • NTRIP Client / Server: ~10-15 KB ciascuno
  • MQTT esp-mqtt client: ~12 KB
  • SD logger + buffer: ~5 KB
  • PVT TCP server con 4 client: ~8 KB
  • OTA HTTPS + TLS handshake: ~15-20 KB (transitorio, solo durante download)

Confronto modalità radio (heap libero approssimativo)

Modalità Heap libero Note
SPP ~100-110 KB BTDM dual-mode + profilo SPP Classic
BLE ~115-125 KB Solo BLE NUS, niente Classic
WIFI ~140-150 KB BTDM completamente scaricato (mem_release)

Conseguenze pratiche:

  • In SPP ci sono ~30-40 KB in meno disponibili per altri servizi. Se attivi anche NTRIP + MQTT + SD logging contemporaneamente, sei più vicino al limite di stabilità.
  • BLE è un buon compromesso quando serve Bluetooth ma vuoi più heap libero (es. cellulari iOS preferiscono BLE).
  • WIFI è la modalità che lascia più heap per servizi di rete avanzati (MQTT publisher con stream NMEA raw, OTA HTTPS, ecc.).

In modalità WIFI (BT scaricato via mem_release) tipicamente si parte da ~140 KB di heap libero. In SPP/BLE con BTDM attivo, ~110 KB.

Meccanismi di protezione automatici

Heap watchdog SD

Quando l’heap libero scende sotto 5 KB (o l’heap minimo storico sotto 4 KB), il logging SD viene sospeso automaticamente per liberare risorse. Riprende quando l’heap torna sopra 10 KB stabili.

Visibile nel menu principale come SD Card (REC paused, low heap).

MQTT giveup

Dopo 6 errori consecutivi di connessione MQTT senza ricevere CONNACK dal broker (~60 secondi di retry), il client si ferma da solo per evitare spam di tentativi e consumo CPU/banda.

Stato visibile nel menu MQTT come On (ERRORE: broker irraggiungibile, premi [R]). Per riprovare correggi config e premi [R].

OTA pre-cleanup

Prima di iniziare il download del firmware via HTTPS, il sistema ferma temporaneamente i servizi heap-heavy:

  • NTRIP Client
  • NTRIP Server
  • SD logging
  • MQTT publisher

Libera ~25-40 KB di heap necessari per TLS handshake e buffer chunk. Al termine dell’OTA (success o failure), i servizi ripartono automaticamente.

MQTT auto-standby in Base
In modalità Base/Caster (tmode ≠ 0) MQTT entra automaticamente in standby (vedi MQTT publisher), liberando ~12 KB. Riprende al ritorno in Rover.
WIFI mode mem release
In modalità WIFI il Bluetooth viene completamente scaricato dalla memoria (esp_bt_controller_mem_release), liberando ~30 KB di heap.
Cleanup di rete prima di azioni critiche

Tutte le operazioni «drastiche» (cambio modalità radio, reboot, spegnimento, OTA) effettuano un cleanup ordinato:

  • Chiusura graceful socket TCP (PVT clients ricevono FIN, non timeout)
  • Pubblicazione last-will MQTT {"alive":false}
  • Chiusura connessioni NTRIP
  • Flush dei buffer SD

Evita perdita di dati e client zombie lato server.

Meccanismi hardware

Brown-out detector (BOD)
Se la tensione di alimentazione scende sotto una soglia critica (~2.5 V, tipico in condizioni di batteria estremamente scarica + picco di corrente WiFi/buzzer), il chip ESP32 esegue un reset hardware automatico. Previene comportamenti imprevedibili dovuti a sottotensione.
Stack overflow monitor

FreeRTOS verifica periodicamente il high-water-mark di ogni task. Loggato in seriale:

STACK-HWM (free byte): APP_TASK=1928 uart_bg=1456 pvt_srv=1768 ntrip_cli=1740 status_led=1732

Valori troppo bassi (<500 byte) indicano rischio stack overflow e vengono segnalati nei log di diagnostica.

Contatori NVS post-mortem

Il firmware mantiene contatori persistenti degli eventi anomali nella partizione NVS, visibili nel menu principale come riga Evt::

Evt: OOM=0 Wi=1 NCli=0 NSrv=0

Dove:

  • OOM — Out-Of-Memory occorsi (alloc fallita)
  • Wi — WiFi disconnections impreviste
  • NCli — NTRIP Client drop
  • NSrv — NTRIP Server drop

La riga compare solo se almeno uno dei counter è > 0. Utile per diagnosticare ricevitori che girano in produzione: dopo settimane si può vedere se ci sono stati eventi critici.

Periodic heap log (seriale)

Ogni ~10 secondi il firmware logga sulla console seriale:

PERIODIC: HEAP free=125044 int=138664 min=104388 [WIFI+WiFi+NCLI+PVT+MQTT]
  • free — heap libero corrente totale
  • int — heap libero in memoria interna (più veloce per WiFi)
  • min — heap minimo storico (low-water-mark): se scende troppo è indicatore di pressione memoria
  • tra parentesi quadre: lista servizi attualmente attivi

Se min scende sotto 30-40 KB, sei vicino al limite di stabilità.

Cosa puoi fare per evitare problemi

Best practice configurazione:

  • Usa modalità WIFI quando puoi: libera 30 KB di heap rispetto a SPP/BLE.
  • Non attivare contemporaneamente NMEA raw MQTT + RTCM3 stream completo + SD logging a 10 Hz: con tutti i messaggi attivi al massimo rate puoi saturare CPU e banda.
  • Per Base statiche, disattiva MQTT (in Base entra in standby comunque, ma se sai che non ti serve mai disattivalo esplicitamente da menu [w][q][t]).
  • Per logging long-running, abilita SD [s][o] Rotazione oraria: file più piccoli, meno rischio FAT32 fragmentation.

Best practice operative:

  • Tieni il broker MQTT raggiungibile via DNS stabile (no IP dinamici): evita timeout connessione che generano errori.
  • Configura il caster NTRIP con un mountpoint valido: in caso contrario il backoff esponenziale tiene il task NCLI sempre attivo (consumo CPU).
  • Verifica periodicamente i contatori Evt: nel menu principale.

Troubleshooting

Riavvii inattesi del ricevitore

Possibili cause in ordine di probabilità:

  1. Brown-out: batteria scarica + WiFi/buzzer attivi contemporaneamente. Ricarica e riprova.
  2. Stack overflow: task con stack-HWM molto basso (<200 byte). Segnala al supporto.
  3. OOM critico: alloc fallita in WiFi/MQTT/TLS. Verifica Evt: OOM=N nel menu.
SD logging si ferma da solo

Heap basso ha sospeso il logging come protezione. Verifica nel menu principale SD Card (REC paused, low heap). Soluzioni:

  • Disattiva NMEA su MQTT ([w][q][n] Off)
  • Riduci NMEA rate da [h][4][n]
  • Passa a modalità WIFI per liberare 30 KB heap
MQTT giveup ricorrente

Il client si ferma dopo 6 errori. Controlla:

  • Broker accessibile da mosquitto_sub esterno?
  • Firewall router/provider blocca la porta MQTT?
  • Credenziali username/password corrette?
  • Vedi MQTT publisher sezione Troubleshooting
Posizione RTK persa frequentemente

Non è quasi mai un problema heap. Verifica:

  • Antenna posizionata con buona vista cielo
  • Distanza dal caster < 30 km
  • Qualità WiFi (RSSI > -75 dBm)

Pagine correlate