使用ESP-IDF的HTTP OTA Demo测试,开启蓝牙功能后,HTTP下载速度就非常慢

这类现象在 ESP32/ESP32-S3 上很常见:只要固件里"启用过 BLE(NimBLE/Controller)",哪怕你在 OTA 前调用了 exit,HTTP OTA 仍可能明显变慢。通常是下面两类原因叠加造成的(你对比"直接注释蓝牙功能的固件"更快,这个对比非常关键)。


1)根因 A:BLE 让 Wi-Fi 走"共存"时隙,吞吐必然掉

Wi-Fi 和 BLE 共用同一个 2.4G 射频前端,打开 BLE 后会进入 RF coexist(时分复用)。

尤其当 BLE 在扫描/连接/较短 interval 广播时,会频繁抢占射频,Wi-Fi 可用 airtime 下降,HTTP 下载速度就会掉。

但你说"已经 exit 了还慢",这说明 不止是射频时隙,还有根因 B。


2)根因 B:即使 BLE "退出",Controller 预留内存/任务/共存状态没彻底释放

很多项目里 nimble_port_deinit() + esp_bt_controller_deinit() 之后,BT controller 的内存并不会自动回收到 heap ,而"未启用蓝牙的固件"天然没有这部分常驻占用,所以 OTA 的 lwIP / TCP / esp_http_client 可用的 内部内存更大、更连续,吞吐更高。

你截图里的 hal_eb_ble_exit() 里虽然做了 stop/deinit/controller_disable/deinit,但缺少最关键的一步:mem_release(以及某些 IDF 版本推荐的 controller deinit API)。


✅建议你按下面做(优先级从高到低)

✅1)在 OTA 前彻底关闭 BLE,并释放 BT Controller 内存(最关键)

把 exit 做成"完整关停 + 释放内存"的版本(注意顺序):

复制代码
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_log.h"

void hal_eb_ble_exit_for_ota(void)
{
    // 1) 先停止所有 BLE 行为(广告/扫描/连接)
    //    视你的代码情况调用:ble_gap_adv_stop(), ble_gap_disc_cancel(), 断开连接等

    // 2) 停 NimBLE host task
    nimble_port_stop();
    vTaskDelay(pdMS_TO_TICKS(200));
    nimble_port_deinit();

    // 3) 关 controller(不同 IDF 可能有更推荐的 API)
    esp_bt_controller_disable();
    esp_bt_controller_deinit();

    // 4) ★释放 controller 占用的内存给系统(没有这步,和"注释蓝牙"差距会很大)
    esp_err_t err = esp_bt_controller_mem_release(ESP_BT_MODE_BLE);
    ESP_LOGI("BLE", "mem_release BLE ret=%d", err);

    // 如果你工程里从来不用经典蓝牙,也可以在启动时就释放 CLASSIC 内存:
    // esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
}

你现在测到"编译时注释 BLE 更快",极大概率就是因为这一块 controller 常驻内存没回收,导致 OTA 期间 lwIP/TLS/HTTP 缓冲不足、碎片化更严重。

验证方法:在 OTA 开始前后打印内部 heap 和最大连续块:

复制代码
ESP_LOGI("MEM", "internal free=%u, largest=%u",
         heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
         heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));

如果加了 mem_release() 后这两个数明显上涨,基本就坐实了。


✅2)如果 OTA 时仍需要 BLE 常开:降低 BLE 对 Wi-Fi 的"射频打扰"

如果你的业务要求 BLE 不能完全关(比如给小程序持续广播),那就只能"让 BLE 更温柔":

  • 停止扫描(scan 对 coexist 影响最大)

  • 广播间隔拉大(比如 100ms→500ms/1000ms)

  • 若连接态:conn interval 拉大(如 30ms→60~120ms),并减少 notify 频率

  • OTA 期间直接 暂停 notify/广播,OTA 完再恢复(最有效)


✅3)把 NimBLE host task 放到另外一个核/降低优先级(减少 CPU 抢占)

Wi-Fi/LwIP 在某些场景对 CPU 调度很敏感。nimble_port_freertos_init() 默认创建 host task,你可以:

  • 把 BLE host task pin 到 core1(Wi-Fi 通常在 core0 更重)

  • 降低 BLE host task priority(不要高过 tcpip、http、ota 相关任务)

(不同 IDF/NimBLE glue 方式不一样,你当前是 nimble_port_freertos_init(ble_host_task),如果你的 ble_host_task 是自己创建的任务,可在创建时 pin/priority。)


✅4)Wi-Fi 侧配置:关省电、提高吞吐稳定性

在 menuconfig 或运行时确保:

  • Wi-Fi power save 关闭(modem sleep 会让吞吐更抖)

    • esp_wifi_set_ps(WIFI_PS_NONE);
  • 信号弱时 BLE coexist 更明显:尽量在 OTA 时保证 RSSI 好一点(>-60dBm)


一句话结论

你现在"exit 了还慢",最像的是:蓝牙 controller 内存没有释放(mem_release 缺失) + coexist 机制/任务调度带来的残余影响

先把 esp_bt_controller_mem_release(ESP_BT_MODE_BLE) 加上再测,通常就能把"和注释蓝牙固件的差距"拉回去一大截。

如果你愿意,把你 OTA 开始前后打印的:

  • internal free / largest block

  • OTA 下载速度(KB/s)

  • 你 BLE 是否处于扫描/连接/仅广播(以及 interval)

相关推荐
andxe6 小时前
安科士 AndXe 技术博客:400G QSFP112 SR4 光模块|AI 算力与超算短距互联最优方案
网络·人工智能·光模块·光通信
shiyi.十一7 小时前
第2章:应用层 — 知识要点与架构
网络·计算机网络·架构
DFT计算杂谈7 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
水境传感 李兆栋7 小时前
GNSS 位移监测站 :毫米级感知,筑牢安全监测防线
网络
中微极客9 小时前
2026主流AI Agent框架技术选型与性能对比
运维·网络·人工智能
猿的天空13 小时前
机器人双手迎来全栈训练系统:灵初智能EgoSteer让灵巧手无所不能
网络·人工智能·计算机·ai·程序员·机器人·编程
Xzaveir_77713 小时前
OPPO、vivo、荣耀号码认证:多终端拨测矩阵与异常复现
大数据·网络·科技·矩阵·产品经理·ai-native
wuqingshun31415913 小时前
从网络角度来看,用户从输入网址到网页显示,期间发生了什么?
网络
牛马工作号13 小时前
Zigbee 专业详解:从协议到排障
网络·物联网·安全
牛马工作号14 小时前
Wi‑Fi 完全指南:从 802.11 协议到 Wi‑Fi 7、AC+AP 与 Mesh 工程组网
网络·网络协议·智能路由器