You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WT32-ETH01板卡BLE与ETH同时启用频繁复位问题求助

WT32-ETH01同时启用ETH与BLE时频繁复位的解决方案

问题现象

WT32-ETH01板卡单独使用以太网(ETH)或BLE功能均正常,但同时编译启用两者时会频繁复位。经排查确认ETH.begin()与BLEDevice::init()存在冲突:BLEDevice::init()基于FreeRTOS使用vTaskDelay进行延时,而ETH.begin()使用Arduino标准的阻塞式delay(),两者的延时机制不兼容是问题的核心原因。

复现代码

#include <ETH.h>
#include <WiFi.h>

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

/* 
   * ETH_CLOCK_GPIO0_IN   - 默认:外部晶振时钟
   * ETH_CLOCK_GPIO0_OUT  - 内部APLL输出50MHz时钟到GPIO0 - LAN8720可能需要反相器
   * ETH_CLOCK_GPIO16_OUT - 内部APLL输出50MHz时钟到GPIO16 - LAN8720可能需要反相器
   * ETH_CLOCK_GPIO17_OUT - 内部APLL反相输出50MHz时钟到GPIO17 - 已在LAN8720上测试通过
*/
#define ETH_CLK_MODE    ETH_CLOCK_GPIO17_OUT

// 外部晶振使能引脚(-1表示禁用,使用内部APLL源)
#define ETH_POWER_PIN   16  // GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT

// 以太网PHY类型(LAN8720或TLK110)
#define ETH_TYPE        ETH_PHY_LAN8720

// 以太网PHY的I²C地址(LAN8720为0或1,TLK110为31)
#define ETH_ADDR        1

// 以太网PHY的I²C时钟引脚
#define ETH_MDC_PIN     23  // GPIO23, VSPID, HS1_STROBE

// 以太网PHY的I²C IO引脚
#define ETH_MDIO_PIN    18  // GPIO18, VSPICLK, HS1_DATA7

void setup()
{
   Serial.begin(115200);

   // 创建并命名BLE设备
   BLEDevice::init("DEVICE_NAME");
   
   Serial.println("DEBUG_1"); // 调试输出
   
   ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);

   Serial.println("DEBUG_2"); // 调试输出
}
void loop()
{}

解决方法

方案1:调整初始化顺序

先完成ETH的初始化(阻塞式操作),再启动BLE设备。这样ETH初始化时的delay()不会干扰已经启动的FreeRTOS BLE任务,避免调度冲突。修改后的setup函数如下:

void setup()
{
   Serial.begin(115200);
   
   // 先初始化ETH
   ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
   Serial.println("ETH initialized");

   // 再初始化BLE
   BLEDevice::init("DEVICE_NAME");
   Serial.println("BLE initialized");
}

方案2:替换ETH库中的阻塞延时为FreeRTOS延时

如果允许修改ETH库源码,找到ETH.begin()内部使用delay()的位置,将其替换为FreeRTOS的vTaskDelay(pdMS_TO_TICKS(延时毫秒数))。这样ETH初始化也使用FreeRTOS的非阻塞延时,与BLE的调度机制保持一致,从根源解决冲突。

方案3:将ETH初始化放入独立FreeRTOS任务

创建一个单独的FreeRTOS任务来执行ETH初始化,让ETH和BLE的任务在操作系统调度下并行运行,避免阻塞式延时影响BLE任务的执行:

void ethInitTask(void *pvParameters)
{
   ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
   Serial.println("ETH initialized in task");
   // 初始化完成后可以删除任务
   vTaskDelete(NULL);
}

void setup()
{
   Serial.begin(115200);

   // 先初始化BLE
   BLEDevice::init("DEVICE_NAME");
   Serial.println("BLE initialized");

   // 创建ETH初始化任务,优先级与BLE任务相当
   xTaskCreate(ethInitTask, "ETH_Init", 2048, NULL, 5, NULL);
}

内容的提问来源于stack exchange,提问作者Nic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 03:52:47