代码改动: - AudioLoop 加 vTaskDelay(1),让出 Core 1 idle task 防 WiFi/RTC 饥饿 - BackgroundTask 优先级 2 → 5,提升 Opus 解码实时性 - LVGL 刷新 5ms → 16ms (60Hz),CPU 占用降 60% - GIF 定时器 20ms → 33ms (3 处),PSRAM 流量减半 - AI 字幕推送 100ms 节流,避免 LVGL 锁争抢 - EnterIdleHibernate 清空 audio_decode_queue_,防 standby_sound 残留误触发首帧 - PowerSaveTimer OnEnterSleepMode 加 device_state 守卫,拦截 dialog/connecting 期间关功放(修复欢迎语期间被静音 bug) - 取消开机 ADC 阻塞采样,开机播报响应从 6 秒缩到 < 3 秒 新增规划: - Phase 7 占位文档:电量保护 + PowerSaveTimer 重构 + 唤醒杂音根治 + RTC 抖动缓解 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.1 KiB
C++
68 lines
2.1 KiB
C++
#include "background_task.h"
|
||
|
||
#include <esp_log.h>
|
||
#include <esp_task_wdt.h>
|
||
|
||
#define TAG "BackgroundTask"
|
||
|
||
BackgroundTask::BackgroundTask(uint32_t stack_size) {
|
||
// 卡顿优化 2: priority 2 → 5
|
||
// 避免 AI Opus 解码被 main_loop(pri 4)延迟,提升音频实时性
|
||
xTaskCreate([](void* arg) {
|
||
BackgroundTask* task = (BackgroundTask*)arg;
|
||
task->BackgroundTaskLoop();
|
||
}, "background_task", stack_size, this, 5, &background_task_handle_);
|
||
}
|
||
|
||
BackgroundTask::~BackgroundTask() {
|
||
if (background_task_handle_ != nullptr) {
|
||
vTaskDelete(background_task_handle_);
|
||
}
|
||
}
|
||
|
||
void BackgroundTask::Schedule(std::function<void()> callback) {
|
||
std::lock_guard<std::mutex> lock(mutex_);
|
||
if (active_tasks_ >= 30) {
|
||
int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||
// 注释说明:为避免非关键日志刷屏,内存阈值告警降级为 DEBUG 并默认关闭
|
||
// if (free_sram < 10000) {
|
||
// ESP_LOGD(TAG, "active_tasks_ == %u, free_sram == %u", active_tasks_.load(), free_sram);
|
||
// }
|
||
}
|
||
// 记录活跃任务计数,作为队列饱和与完成条件的依据
|
||
active_tasks_++;
|
||
main_tasks_.emplace_back([this, cb = std::move(callback)]() {
|
||
cb();
|
||
{
|
||
std::lock_guard<std::mutex> lock(mutex_);
|
||
active_tasks_--;
|
||
if (main_tasks_.empty() && active_tasks_ == 0) {
|
||
condition_variable_.notify_all();
|
||
}
|
||
}
|
||
});
|
||
condition_variable_.notify_all();
|
||
}
|
||
|
||
void BackgroundTask::WaitForCompletion() {
|
||
std::unique_lock<std::mutex> lock(mutex_);
|
||
condition_variable_.wait(lock, [this]() {
|
||
return main_tasks_.empty() && active_tasks_ == 0;
|
||
});
|
||
}
|
||
|
||
void BackgroundTask::BackgroundTaskLoop() {
|
||
ESP_LOGI(TAG, "background_task started");
|
||
while (true) {
|
||
std::unique_lock<std::mutex> lock(mutex_);
|
||
condition_variable_.wait(lock, [this]() { return !main_tasks_.empty(); });
|
||
|
||
std::list<std::function<void()>> tasks = std::move(main_tasks_);
|
||
lock.unlock();
|
||
|
||
for (auto& task : tasks) {
|
||
task();
|
||
}
|
||
}
|
||
}
|