feat(spi_link): 添加SPI Link v2 PC自测框架并优化协议稳定性
SPI Link v2 Self-Test / selftest (push) Has been cancelled
SPI Link v2 Self-Test / selftest (push) Has been cancelled
添加SPI Link v2的PC端自测功能,包含交叉校验基准测试,覆盖HELLO/OTA/CAN/PING等 多种协议场景。同时重构了health monitor中的多字段读取逻辑,消除了volatile变量 的撕裂读问题,并增强了BLE OTA的数据传输可靠性。 refactor(health_monitor): 修复heap hook多字段撕裂读问题 采用portMUX_CRITICAL临界区实现多字段一致快照读取,消除任务上下文与heap hook 之间的数据竞争。修改了HookSnap结构体设计,通过一次性拷贝volatile变量避免 跨字段组合时的数据不一致。JSON输出中明确标注estimated值的置信度。 fix(ble_ota): 实现DATA_IN丢包负反馈机制 当malloc失败或队列满时发送缺口ACK通知前端按completed_bytes续传,避免 静默丢包导致的8秒超时重传风暴。增加节流机制防止负ACK在重传叠加时打爆 NimBLE mbuf池,提升低内存环境下的OTA传输稳定性。 refactor(spi_master): 从堆分配改为固定Job池管理 将SPI worker的动态堆分配Job改为固定大小的静态池管理,避免频繁的 calloc/free操作影响实时性。新增acquireJobSlot/releaseJobSlot机制 管理池槽生命周期,提升SPI通信的可靠性和内存使用效率。
This commit is contained in:
@@ -99,7 +99,7 @@ public:
|
||||
/** @brief SPI worker 任务句柄(栈水位 /system/status 与 health 巡检用)。 */
|
||||
TaskHandle_t getWorkerTaskHandle() const { return m_workerTask; }
|
||||
|
||||
/** @brief SPI 任务队列当前待处理 job 数(每个堆 Job 持有 calloc 的 Job 结构)。
|
||||
/** @brief SPI 任务队列当前待处理 job 数(固定 Job pool 槽,无堆分配)。
|
||||
* 供 /system/heap_low_log 堆低水位快照采样,定位"低谷是不是 SPI 队列堆积引起"。 */
|
||||
UBaseType_t getPendingJobCount() const { return m_jobQueue ? uxQueueMessagesWaiting(m_jobQueue) : 0; }
|
||||
|
||||
@@ -302,7 +302,7 @@ private:
|
||||
uint8_t m_eventTail = 0;
|
||||
uint8_t m_eventCount = 0;
|
||||
|
||||
// ── 作业提交(跨任务:堆 Job + binary done;worker 串行执行)──
|
||||
// ── 作业提交(跨任务:固定 Job pool + 静态 binary done;worker 串行执行)──
|
||||
enum class JobKind : uint8_t {
|
||||
Transact = 0,
|
||||
Poll,
|
||||
@@ -326,19 +326,27 @@ private:
|
||||
uint32_t *out_uptime = nullptr;
|
||||
gd32_version_t *out_version = nullptr;
|
||||
esp_err_t result = ESP_FAIL;
|
||||
SemaphoreHandle_t done = nullptr;
|
||||
/** submitJob 堆分配的 Job:超时放弃后由 worker 释放,成功路径由提交方释放。 */
|
||||
bool heap_allocated = false;
|
||||
SemaphoreHandle_t done = nullptr; ///< 池槽静态 binary,init 创建,永不 delete
|
||||
volatile bool finished = false; ///< worker 已 execute + give
|
||||
volatile bool abandoned = false; ///< 提交方已超时返回,worker 负责 free
|
||||
volatile bool abandoned = false; ///< 提交方已超时返回,worker 负责 release 槽
|
||||
bool in_use = false; ///< 池槽占用(critical 保护)
|
||||
};
|
||||
/** 队列深度;池 = 队列 + 1(在途执行槽),覆盖 queued + executing。 */
|
||||
static constexpr UBaseType_t kJobQueueLen = 6;
|
||||
static constexpr UBaseType_t kJobPoolSize = kJobQueueLen + 1U;
|
||||
|
||||
Job m_jobPool[kJobPoolSize] = {};
|
||||
bool m_jobPoolReady = false;
|
||||
|
||||
bool onWorker() const;
|
||||
/** @brief 从固定池取空闲 Job;池耗尽返回 nullptr(ESP_ERR_NO_MEM)。 */
|
||||
Job *acquireJobSlot();
|
||||
/** @brief 归还池槽(清空业务字段/标志,drain done 信号量)。 */
|
||||
void releaseJobSlot(Job *job);
|
||||
esp_err_t submitJob(Job &job);
|
||||
void executeJob(Job &job);
|
||||
/** @brief worker 完成堆 Job 后的生命周期收尾(give done + 可能 free)。 */
|
||||
void finishHeapJob(Job *job);
|
||||
/** @brief worker 完成池 Job 后的收尾(give done;abandoned 时 release 槽)。 */
|
||||
void finishPoolJob(Job *job);
|
||||
/** @brief FreeRTOS 任务入口,转到 workerLoop。 */
|
||||
static void workerEntry(void *arg);
|
||||
/** @brief SPI worker 主循环:EVENT 按铃 + Job 队列。 */
|
||||
|
||||
Reference in New Issue
Block a user