feat(spi): 增强 SPI master:性能剖析与执行耗时跟踪
- 新增 `lastWorkerExecUs()`:获取最近一次 worker 任务执行耗时(µs)。 - 引入 `SpiProfile` 结构体:事务级详细剖析,记录 SPI 事务各阶段的时间戳。 - 实现 `lastProfile()`:诊断用,获取最近一次事务剖析快照。 - SPI 时钟配置提升至 13.3 MHz,改善性能。 - 修改前端 JavaScript 轮询逻辑:新增 uptime 检查,更好地处理 ESP32 重启状态。 - SPI 测速 HTML 的计时单位由毫秒改为微秒显示。 - 新建 `spi_ring_cache.h`:共享 SPI ring push 缓存工具。 - 新增 `http_util.h`:共享 HTTP 处理器工具,含 JSON 拼接与查询参数解析。 - 引入 `json_parse.h`:轻量级 JSON 解析器,针对扁平 JSON 对象设计。 - 新增 Windows 环境下的项目构建批处理脚本。 - 重构 CAN 反馈处理:从推送式改为请求驱动架构,降低内存占用、提升效率。
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "mbedtls/private/sha256.h"
|
||||
|
||||
#include "gd32_flash_store.h"
|
||||
#include "app_config.h" // OTA_BLOCK_SIZE(flashWriteChunk 静态对齐缓冲容量)
|
||||
#include "monitor/debug_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -147,6 +148,54 @@ esp_err_t Gd32FlashStore::ensureErasedForWrite(uint32_t offset, size_t len)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// OTA 期对齐缓冲池(2026-08 内存优化)
|
||||
//
|
||||
// flashWriteChunk 在非 4 字节对齐写入时需要临时缓冲读回 padding。
|
||||
// 原实现每次 malloc/free,OTA 收流时与非对齐块叠加产生堆抖动。
|
||||
// 现改为 OTA begin 时一次性 calloc,end/abort 时 free,消除抖动
|
||||
// 又不增加常驻 BSS(非 OTA 期零占用)。
|
||||
// ============================================================
|
||||
static uint8_t *s_align_buf = nullptr;
|
||||
static constexpr size_t kAlignBufCap = OTA_BLOCK_SIZE + 8;
|
||||
|
||||
void Gd32FlashStore::acquireAlignBufForOta()
|
||||
{
|
||||
if (!s_align_buf) {
|
||||
s_align_buf = (uint8_t *)calloc(1, kAlignBufCap);
|
||||
if (!s_align_buf) {
|
||||
DEBUG_WARN("OTA", "对齐缓冲分配失败,回退 malloc free=%u",
|
||||
(unsigned)esp_get_free_heap_size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gd32FlashStore::releaseAlignBufForOta()
|
||||
{
|
||||
if (s_align_buf) {
|
||||
free(s_align_buf);
|
||||
s_align_buf = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief 取对齐缓冲。优先用 OTA 期预分配;未分配或太小则临时 malloc。 */
|
||||
static uint8_t *acquireAlignBuf(size_t needed)
|
||||
{
|
||||
if (s_align_buf && needed <= kAlignBufCap) {
|
||||
return s_align_buf;
|
||||
}
|
||||
// OTA 未预分配(begin 失败)或包过大:回退临时 malloc
|
||||
return (uint8_t *)malloc(needed);
|
||||
}
|
||||
|
||||
/** @brief 归还对齐缓冲。OTA 池的不释放;临时 malloc 的 free。 */
|
||||
static void releaseAlignBuf(uint8_t *buf)
|
||||
{
|
||||
if (buf && buf != s_align_buf) {
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief 向 gd32_ota 分区写入数据块,自动处理非 4 字节对齐的读写。 */
|
||||
esp_err_t Gd32FlashStore::flashWriteChunk(uint32_t offset, const uint8_t *data, size_t len)
|
||||
{
|
||||
@@ -188,9 +237,12 @@ esp_err_t Gd32FlashStore::flashWriteChunk(uint32_t offset, const uint8_t *data,
|
||||
offset, len, head_pad);
|
||||
}
|
||||
|
||||
uint8_t *aligned_buf = (uint8_t *)malloc(aligned_len);
|
||||
/* OTA 期按需对齐缓冲(OTA begin 时 calloc,end/abort 时 free):
|
||||
* 消除每非对齐块的 malloc/free 抖动,又不增加常驻 BSS。
|
||||
* 容量 = OTA_BLOCK_SIZE(4KB) + 最多 3 字节 tail pad。 */
|
||||
uint8_t *aligned_buf = acquireAlignBuf(aligned_len);
|
||||
if (!aligned_buf) {
|
||||
DEBUG_ERR("OTA", "flashWriteChunk malloc失败: %zu字节", aligned_len);
|
||||
DEBUG_ERR("OTA", "flashWriteChunk 对齐缓冲不足/未分配: %zu", aligned_len);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
@@ -200,7 +252,7 @@ esp_err_t Gd32FlashStore::flashWriteChunk(uint32_t offset, const uint8_t *data,
|
||||
if (err != ESP_OK) {
|
||||
DEBUG_ERR("OTA", "flashWriteChunk读回head失败: offset=%" PRIu32 " head=%zu err=%s",
|
||||
aligned_offset, head_pad, esp_err_to_name(err));
|
||||
free(aligned_buf);
|
||||
releaseAlignBuf(aligned_buf);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -215,13 +267,13 @@ esp_err_t Gd32FlashStore::flashWriteChunk(uint32_t offset, const uint8_t *data,
|
||||
if (err != ESP_OK) {
|
||||
DEBUG_ERR("OTA", "flashWriteChunk读回tail失败: offset=%" PRIu32 " tail=%zu err=%s",
|
||||
aligned_offset + total, tail_pad, esp_err_to_name(err));
|
||||
free(aligned_buf);
|
||||
releaseAlignBuf(aligned_buf);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t err = esp_partition_write(part, aligned_offset, aligned_buf, aligned_len);
|
||||
free(aligned_buf);
|
||||
releaseAlignBuf(aligned_buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,12 @@ public:
|
||||
*/
|
||||
const esp_partition_t* getPartition();
|
||||
|
||||
// ── OTA 期对齐缓冲生命周期 ──
|
||||
/** @brief GD32 OTA begin 时调用:预分配对齐缓冲(消除 flashWriteChunk 逐块 malloc)。 */
|
||||
static void acquireAlignBufForOta();
|
||||
/** @brief GD32 OTA end/abort 时调用:释放对齐缓冲(非 OTA 期零占用)。 */
|
||||
static void releaseAlignBufForOta();
|
||||
|
||||
private:
|
||||
Gd32FlashStore();
|
||||
~Gd32FlashStore() = default;
|
||||
|
||||
Reference in New Issue
Block a user