From 2458c4e8bc6fd7bbe61496608bba1c6f5c724dab Mon Sep 17 00:00:00 2001 From: Rdzleo Date: Thu, 21 May 2026 12:02:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(ble):=20=E5=85=B3=E9=97=AD=20BLE=205.0=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E9=87=8A=E6=94=BE=20controller=20DRAM,=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=85=8D=E7=BD=91=E5=B9=BF=E6=92=AD=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20malloc=20=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 日志: E (3731) BLE_INIT: Malloc failed E (3731) BT_HCI: CC evt: op=0x2008 (HCI_BLE_WRITE_ADV_DATA), status=0x7 E (3731) BLE_INIT: Malloc failed E (3731) BT_HCI: CC evt: op=0x2009 (HCI_BLE_WRITE_SCAN_RSP), status=0x7 I (3731) BluetoothProvisioning: ✅ 广播启动成功 代码层"广播启动成功", 但 HCI 层 ADV_DATA + SCAN_RSP_DATA 都没写入 → 广播空数据 → 手机搜不到设备. 根因: sdkconfig 同时启用了 BLE 5.0 + 4.2 全套特性, 但项目代码实际只用 4.2 legacy advertising (esp_ble_adv_params_t / esp_ble_gap_start_advertising). BLE 5.0 6 个特性总和占用 controller DRAM, 让 HCI ADV_DATA / SCAN_RSP_DATA 内存池耗尽. 修复: sdkconfig 关闭所有 BLE 5.0 特性 (项目实际不用): # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set # CONFIG_BT_BLE_50_EXTEND_ADV_EN is not set # CONFIG_BT_BLE_50_PERIODIC_ADV_EN is not set # CONFIG_BT_BLE_50_EXTEND_SCAN_EN is not set # CONFIG_BT_BLE_50_EXTEND_SYNC_EN is not set # CONFIG_BT_BLE_50_DTM_TEST_EN is not set 保留 CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y (legacy advertising 必需). dzbj_ble.c:458 用了 esp_ble_gap_set_preferred_phy (BLE 5.0 API), 但有 #if (BLE_50_FEATURE_SUPPORT == TRUE) 保护, 关闭后编译自动跳过, 不影响其他功能. 附加: 修复 BOOT 触发配网时音效不响 wifi_board.cc::ResetWifiConfiguration(): - 移除直接 vTaskDelay (iot_button 回调跑在 esp_timer task, 实测 vTaskDelay 4000ms 只等了 1.1s) - 改用 xTaskCreate("wifi_reset") 独立 task 跑: PlaySound + vTaskDelay(4000) + esp_restart - 在重启前播完配网音效 wifi_board.cc::EnterWifiConfigMode(): - 移除之前在 BLE 配网成功后重复 PlaySound 的代码 (StartBleProvisioning 内部 Alert 已经调用过) 注: codec output_only 仍保持 NeedsProvisioning() (TX-only + ES8311-only). 强制 duplex 会让 BLE Bluedroid gatt_init malloc failed → assert reboot loop, 已验证. 待解决 (留待 adaptation_dzbjImg_shar 分支对比): - 关闭 BLE 5.0 后手机可搜到设备, 但点击连接失败 - 配网模式下 P3_LALA_WIFICONFIG 音效仍不响 (StartBleProvisioning 内 Alert 调用但 audio_loop 似乎没消费) Co-Authored-By: Claude Opus 4.7 (1M context) --- main/application.cc | 2 + main/boards/common/wifi_board.cc | 42 ++++++++++++------- .../movecall_moji_esp32s3.cc | 2 + sdkconfig | 7 +--- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/main/application.cc b/main/application.cc index c4f60be..90c481a 100644 --- a/main/application.cc +++ b/main/application.cc @@ -800,6 +800,8 @@ void Application::Start() { if (provisioning_mode_) { // 配网模式:跳过编码器、输入重采样器,仅启用扬声器输出 + // ⚠️ 不要改成完整 codec->Start(): 配网模式下 BLE 需要 ~15KB DRAM, + // duplex codec 会让 BLE gatt_init malloc failed → reboot loop ESP_LOGI(TAG, "配网模式:跳过 Opus 编码器、输入重采样器、麦克风输入"); codec->StartOutputOnly(); } else { diff --git a/main/boards/common/wifi_board.cc b/main/boards/common/wifi_board.cc index 1ab0d09..36b2422 100644 --- a/main/boards/common/wifi_board.cc +++ b/main/boards/common/wifi_board.cc @@ -352,22 +352,34 @@ void WifiBoard::SetPowerSaveMode(bool enabled) { // 重置WiFi配置,设备将重启进入配网模式 void WifiBoard::ResetWifiConfiguration() { ESP_LOGI(TAG, "🔄 重置WiFi配置,设备将重启进入配网模式"); - // 设置WiFi配网标志位,确保重启后能正确进入配网模式 - { - Settings settings("wifi", true);// 创建WiFi配置设置对象,第二个参数true表示立即保存到NVS存储 - settings.SetInt("force_ap", 1);// 设置force_ap标志为1,这个标志会在设备重启后被检查,如果为1则启动WiFi配网服务,启动时强制进入AP配网模式 - } - // 获取显示设备对象并显示配网提示信息 - auto display = GetDisplay(); - if (display) { - // 在屏幕上显示"进入WiFi配置模式"的多语言提示信息 - // 让用户知道设备即将重启并进入配网模式 - display->ShowNotification(Lang::Strings::ENTERING_WIFI_CONFIG_MODE); - } - vTaskDelay(pdMS_TO_TICKS(500)); // 等待500ms,确保NVS配置保存完成,如果有屏幕显示,可以增加到1000ms让用户看清提示 - ESP_LOGI(TAG, "🔄 正在重启设备..."); - esp_restart(); // 重启设备,重启后会进入配网模式 + // ⚠️ ResetWifiConfiguration 由 BOOT 按键 OnClick 调用, 跑在 esp_timer task 上下文. + // CLAUDE.md 警告: iot_button 回调在 esp_timer task 中执行, 不能 vTaskDelay + // (4000ms vTaskDelay 实测只等了 1100ms 就被唤醒, 音效没播完就 esp_restart). + // 修复: 派发整个"播音效 + 等待 + 重启"逻辑到独立 task 跑. + xTaskCreate([](void* /*arg*/) { + ESP_LOGI("WifiBoard", "🔄 [reset_task] 开始播放配网音效..."); + auto& application = Application::GetInstance(); + if (strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0) { + application.PlaySound(Lang::Sounds::P3_KAKA_WIFICONFIG); + } else if (strcmp(CONFIG_DEVICE_ROLE, "RTC_Test") == 0) { + application.PlaySound(Lang::Sounds::P3_LALA_WIFICONFIG); + } + // 等 4 秒让音效完整播完 (在独立 task 中 vTaskDelay 正常工作) + // 覆盖: 入队 + audio_loop 出队 + background_task 解码 + I2S DMA + 功放尾音 + vTaskDelay(pdMS_TO_TICKS(4000)); + ESP_LOGI("WifiBoard", "🔄 [reset_task] 配网音效播放完成"); + + // 设置 force_ap 标志, 让设备重启后进入配网模式 + { + Settings settings("wifi", true); + settings.SetInt("force_ap", 1); + } + ESP_LOGI("WifiBoard", "🔄 [reset_task] 正在重启设备..."); + esp_restart(); + vTaskDelete(NULL); // 不应执行到这里 + }, "wifi_reset", 4096, NULL, 5, NULL); + // ResetWifiConfiguration 立刻 return, 不阻塞 BOOT 按键回调 } // 启动BLE配网服务 diff --git a/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc b/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc index de582ea..bad7a1b 100644 --- a/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc +++ b/main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc @@ -1582,6 +1582,8 @@ public: init_attempted = true; // 标记为已尝试初始化 // 配网模式:仅创建 TX 通道,跳过 RX DMA(~11.5KB)和 ES7210(~2-4KB) + // ⚠️ 不要改成 false: 配网模式下 BLE Bluedroid stack 需要这 15KB DRAM, + // 强制 duplex 会让 BLE gatt_init 时 malloc failed → assert reboot loop bool output_only = WifiBoard::NeedsProvisioning(); ESP_LOGI(TAG, "Initializing audio codec (%s)...", output_only ? "output only" : "duplex"); diff --git a/sdkconfig b/sdkconfig index 42d62f5..a5a3dcf 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1038,12 +1038,7 @@ CONFIG_BT_SMP_MAX_BONDS=15 # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_MAX_DEVICE_NAME_LEN=32 CONFIG_BT_BLE_RPA_TIMEOUT=900 -CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -CONFIG_BT_BLE_50_EXTEND_ADV_EN=y -CONFIG_BT_BLE_50_PERIODIC_ADV_EN=y -CONFIG_BT_BLE_50_EXTEND_SCAN_EN=y -CONFIG_BT_BLE_50_EXTEND_SYNC_EN=y -CONFIG_BT_BLE_50_DTM_TEST_EN=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y CONFIG_BT_BLE_42_DTM_TEST_EN=y CONFIG_BT_BLE_42_ADV_EN=y