Files
MeshCoreTel-firmware/arch/esp32/CPUUsageTracker.h
T
Valentin V. Bartenev a6f01d544e ESP32: add CPUUsageTracker – core-0 load averages (1/5/15 min)
Track CPU utilisation on core 0 using a FreeRTOS tick hook that
increments per-tick idle/busy counters, sampled every 5s by an
esp_timer callback.  Exponential moving averages with Linux-style
time constants (1 / 5 / 15 min) are maintained in software:

  DECAY1  = exp(-5/60)  ≈ 0.9200  (1-minute window)
  DECAY5  = exp(-5/300) ≈ 0.9835  (5-minute window)
  DECAY15 = exp(-5/900) ≈ 0.9945  (15-minute window)

Core 1 is excluded intentionally: it runs the Arduino loopTask at
100% load for LoRa packet processing, so its figure is always 1.0
and carries no diagnostic value.  All other tasks are pinned to
core 0 by task_pinning.c, so core-0 load reflects the true system
utilisation.

New files:
  arch/esp32/CPUUsageTracker.h   – class declaration
  arch/esp32/CPUUsageTracker.cpp – tick hook + esp_timer sampling

Integration:
  MyMesh::begin() calls _cpu_tracker.begin() on ESP32 builds.
  formatStatsReply() emits "load_avg":[<1m>,<5m>,<15m>] in the
  compact stats JSON payload.
  formatWebStatsSummaryJson() adds the same field to the web-panel
  stats endpoint under core.load_avg.
  The web-panel HUD gains a "Load Avg" metric tile showing all
  three values side-by-side; the core-metrics grid is widened from
  4 to 5 columns.  The tile is rendered conditionally so older
  firmware (or non-ESP32 builds) that omit the field degrade
  gracefully.
  CPUUsageTracker.cpp is added to the esp32_base build_src_filter
  in platformio.ini.
2026-05-09 17:26:27 +03:00

41 строка
988 B
C++

#pragma once
#ifdef ESP32
#include <stdint.h>
#include "esp_attr.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
class CPUUsageTracker {
public:
void begin();
float getLoadAvg1() const { return _avg1; }
float getLoadAvg5() const { return _avg5; }
float getLoadAvg15() const { return _avg15; }
private:
static constexpr float DECAY1 = 0.920044415f; // exp(-5/60)
static constexpr float DECAY5 = 0.983471454f; // exp(-5/300)
static constexpr float DECAY15 = 0.994459848f; // exp(-5/900)
static volatile uint32_t s_idle_ticks;
static volatile uint32_t s_busy_ticks;
static TaskHandle_t s_idle_handle;
static void IRAM_ATTR s_tick_hook();
static void s_sample_cb(void* arg);
uint32_t _last_idle = 0;
uint32_t _last_busy = 0;
float _avg1 = 0.0f;
float _avg5 = 0.0f;
float _avg15 = 0.0f;
esp_timer_handle_t _timer = nullptr;
void _onSample();
};
#endif