feat(ota): 实现GD32 OTA包间背压机制,优化传输节奏控制
移除固定的包间延迟配置 `OTA_PACKET_DELAY_MS`,采用基于SPI Link v2 CREDIT背压的动态节奏控制,在SpiMaster中通过remoteCredit==0时wait/拒发 实现流量控制,提高OTA传输稳定性。 refactor(stack): 统一任务栈大小配置并添加CPU统计功能 - 在app_config.h中集中定义所有任务栈大小常量,基于实测水位优化分配 - 新增monitor/cpu_stats.cpp组件,提供1Hz FreeRTOS CPU占用采样 - 更新main.cpp中的任务创建使用新的栈大小常量 - 调整health_monitor和ota_relay等任务的栈分配 perf(ota): 改进ESP32和GD32 OTA分区预擦策略 - ESP32 OTA从边写边擦改为整分区预擦模式,避免写入时的扇区擦除阻塞 - GD32 OTA在prepare阶段进行整分区预擦,提升后续写入吞吐量 - 优化OTA协调器状态管理,修复FINALIZING状态残留问题 fix(log): 改进UDP日志发送的堆内存管理 - 当堆内存不足时记录UDP发送跳过的告警信息到ring buffer - 降低UDP发送跳过的内存阈值从10KB到6KB - 降低日志排水最小内存阈值从8KB到4KB docs(readme): 更新OTA配置参数文档说明 移除已废弃的OTA_PACKET_DELAY_MS参数,更新包间节奏控制说明为 基于CREDIT背压机制的描述。
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* cpu_stats.h - FreeRTOS 运行时 CPU 占用采样
|
||||
*
|
||||
* 由独立低优先级任务按固定 1s 周期采样;/system/status 只读最新快照,
|
||||
* 不再在 HTTP 线程里调用 uxTaskGetSystemState(避免窗口绑浏览器轮询、减 httpd 栈压)。
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
/** 单次快照最多跟踪的任务数 */
|
||||
static constexpr size_t CPU_TASK_SNAPSHOT_MAX = 32;
|
||||
|
||||
/** 采样周期(ms)— 窗口 sample_ms 应对齐此值 */
|
||||
static constexpr uint32_t CPU_STATS_SAMPLE_MS = 1000;
|
||||
|
||||
struct CpuTaskMetric {
|
||||
char name[configMAX_TASK_NAME_LEN];
|
||||
UBaseType_t task_number;
|
||||
uint64_t runtime_delta;
|
||||
double usage_pct;
|
||||
};
|
||||
|
||||
struct CpuUsageSnapshot {
|
||||
bool available; ///< 固件是否启用 RUN_TIME_STATS
|
||||
bool valid; ///< 是否已有完整窗口(至少两拍)
|
||||
uint32_t sample_ms; ///< 本窗口墙钟长度
|
||||
double usage_pct; ///< 100 - idle
|
||||
double idle_pct;
|
||||
CpuTaskMetric tasks[CPU_TASK_SNAPSHOT_MAX];
|
||||
size_t task_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CPU 运行时统计(单例 + 1Hz 采样任务)
|
||||
*/
|
||||
class CpuStats {
|
||||
public:
|
||||
static CpuStats& instance();
|
||||
|
||||
/** 创建采样任务(幂等;失败仅打日志,不阻塞启动) */
|
||||
void start();
|
||||
|
||||
/** 线程安全拷贝最新快照(HTTP 用) */
|
||||
void getSnapshot(CpuUsageSnapshot& out) const;
|
||||
|
||||
TaskHandle_t getTaskHandle() const { return m_taskHandle; }
|
||||
|
||||
private:
|
||||
CpuStats() = default;
|
||||
|
||||
static void taskEntry(void* arg);
|
||||
void sampleOnce();
|
||||
|
||||
mutable portMUX_TYPE m_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
CpuUsageSnapshot m_published = {};
|
||||
TaskHandle_t m_taskHandle = nullptr;
|
||||
bool m_started = false;
|
||||
|
||||
/* 基线(仅采样任务写) */
|
||||
struct TaskSample {
|
||||
UBaseType_t task_number;
|
||||
configRUN_TIME_COUNTER_TYPE runtime;
|
||||
};
|
||||
TaskSample m_lastSamples[CPU_TASK_SNAPSHOT_MAX] = {};
|
||||
size_t m_lastCount = 0;
|
||||
configRUN_TIME_COUNTER_TYPE m_lastTotal = 0;
|
||||
int64_t m_lastTimeUs = 0;
|
||||
bool m_hasLast = false;
|
||||
};
|
||||
Reference in New Issue
Block a user