mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 23:08:11 +00:00
feat(ui): add on-device diagnostics screen (Tools > Diagnostics)
Shows packet counts by category (RX/TX), radio noise floor/RSSI/SNR, packet-pool free count and outbound queue length, uptime, and heap/stack headroom on a single scrollable screen. Adds generic per-payload-type RX/TX counters to Dispatcher (mesh layer), plus pool-free/queue-length getters, and a new DeviceDiag helper for nRF52 heap (linker-symbol + sbrk) and stack (FreeRTOS high-water-mark) stats — the only platform needed for the 3 in-scope boards (Wio Tracker L1 OLED/Eink, GAT562 30S), all nRF52840. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,8 @@ namespace mesh {
|
||||
void Dispatcher::begin() {
|
||||
n_sent_flood = n_sent_direct = 0;
|
||||
n_recv_flood = n_recv_direct = 0;
|
||||
memset(n_sent_by_type, 0, sizeof(n_sent_by_type));
|
||||
memset(n_recv_by_type, 0, sizeof(n_recv_by_type));
|
||||
_err_flags = 0;
|
||||
radio_nonrx_start = _ms->getMillis();
|
||||
|
||||
@@ -106,6 +108,7 @@ void Dispatcher::loop() {
|
||||
|
||||
_radio->onSendFinished();
|
||||
logTx(outbound, 2 + outbound->getPathByteLen() + outbound->payload_len);
|
||||
n_sent_by_type[outbound->getPayloadType()]++;
|
||||
if (outbound->isRouteFlood()) {
|
||||
n_sent_flood++;
|
||||
} else {
|
||||
@@ -236,6 +239,7 @@ void Dispatcher::checkRecv() {
|
||||
#endif
|
||||
logRx(pkt, pkt->getRawLength(), score); // hook for custom logging
|
||||
|
||||
n_recv_by_type[pkt->getPayloadType()]++;
|
||||
if (pkt->isRouteFlood()) {
|
||||
n_recv_flood++;
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ class Dispatcher {
|
||||
bool prev_isrecv_mode;
|
||||
uint32_t n_sent_flood, n_sent_direct;
|
||||
uint32_t n_recv_flood, n_recv_direct;
|
||||
uint32_t n_sent_by_type[16], n_recv_by_type[16]; // indexed by getPayloadType() (4-bit field)
|
||||
unsigned long tx_budget_ms;
|
||||
unsigned long last_budget_update;
|
||||
unsigned long duty_cycle_window_ms;
|
||||
@@ -184,8 +185,14 @@ public:
|
||||
uint32_t getNumSentDirect() const { return n_sent_direct; }
|
||||
uint32_t getNumRecvFlood() const { return n_recv_flood; }
|
||||
uint32_t getNumRecvDirect() const { return n_recv_direct; }
|
||||
uint32_t getNumSentByType(uint8_t payload_type) const { return n_sent_by_type[payload_type & 0x0F]; }
|
||||
uint32_t getNumRecvByType(uint8_t payload_type) const { return n_recv_by_type[payload_type & 0x0F]; }
|
||||
int getPoolFreeCount() const { return _mgr->getFreeCount(); }
|
||||
int getOutboundQueueLen() const { return _mgr->getOutboundTotal(); }
|
||||
void resetStats() {
|
||||
n_sent_flood = n_sent_direct = n_recv_flood = n_recv_direct = 0;
|
||||
memset(n_sent_by_type, 0, sizeof(n_sent_by_type));
|
||||
memset(n_recv_by_type, 0, sizeof(n_recv_by_type));
|
||||
_err_flags = 0;
|
||||
}
|
||||
|
||||
|
||||
31
src/helpers/DeviceDiag.cpp
Normal file
31
src/helpers/DeviceDiag.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "DeviceDiag.h"
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
// Same linker symbols + _sbrk() the core's own new.cpp uses to implement
|
||||
// malloc's heap (see framework-arduinoadafruitnrf52/cores/nRF5/new.cpp) —
|
||||
// there's no separate "free heap" API on this core, so this mirrors it.
|
||||
extern "C" char* _sbrk(int incr);
|
||||
extern unsigned char __HeapBase[];
|
||||
extern unsigned char __HeapLimit[];
|
||||
|
||||
void DeviceDiag::getHeapStats(uint32_t& free_bytes, uint32_t& total_bytes) {
|
||||
total_bytes = (uint32_t)(__HeapLimit - __HeapBase);
|
||||
uint32_t used = (uint32_t)((unsigned char*)_sbrk(0) - __HeapBase);
|
||||
free_bytes = (used < total_bytes) ? (total_bytes - used) : 0;
|
||||
}
|
||||
|
||||
uint32_t DeviceDiag::getStackFreeBytes() {
|
||||
return (uint32_t)uxTaskGetStackHighWaterMark(NULL) * sizeof(StackType_t);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void DeviceDiag::getHeapStats(uint32_t& free_bytes, uint32_t& total_bytes) {
|
||||
free_bytes = 0; total_bytes = 0;
|
||||
}
|
||||
uint32_t DeviceDiag::getStackFreeBytes() { return 0; }
|
||||
|
||||
#endif
|
||||
10
src/helpers/DeviceDiag.h
Normal file
10
src/helpers/DeviceDiag.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// Cross-platform free-heap / stack-headroom estimate for the on-device
|
||||
// diagnostics screen. A total_bytes of 0 means "not supported on this
|
||||
// platform" — callers should display "N/A" rather than 0/0.
|
||||
struct DeviceDiag {
|
||||
static void getHeapStats(uint32_t& free_bytes, uint32_t& total_bytes);
|
||||
static uint32_t getStackFreeBytes(); // current task's min-ever headroom; 0 = unsupported
|
||||
};
|
||||
Reference in New Issue
Block a user