使用 ESP32 网络服务器下载文件时面临问题
Posted
技术标签:
【中文标题】使用 ESP32 网络服务器下载文件时面临问题【英文标题】:Facing issue with file download using ESP32 webserver 【发布时间】:2021-01-21 07:54:37 【问题描述】:我正在使用带有 Arduino 框架的 PlatformIO 为 ESP32 (16MB) 开发代码,在 ESP32 上,我同时使用蓝牙和 Wi-Fi 连接。当移动应用程序与 ESP32 的蓝牙连接时,数据将使用基于 BLE 特性的蓝牙在移动设备上发送(工作正常),当蓝牙未连接时,数据将记录在 .json 文件中(为此和文件创建使用了 SPIFFS 库工作正常)。当用户想要获取日志数据时,ESP32 将创建 Wi-Fi 接入点 (AP)(使用 WiFi.h)并通过连接到该 AP,用户应该能够通过访问链接“192.168.4.1/download”下载 .json 文件在浏览器上。在移动应用程序上下载文件后,用户将访问链接“192.168.4.1/finisheddownload”,文件将从 ESP32 中删除。
成功连接到 ESP32 的 AP 后,当我从浏览器访问链接“192.168.4.1/download”时,代码会卡在那个点,或者有时它会重新启动 ESP32 并且什么也不执行,如果我访问“192.168.4.1/”完成下载”,它成功删除了文件。我的文件大小约为 10MB,但即使我在文件大小为 1KB 时执行此操作,它的行为也相同。我已经在 ESP32 (4MB) 模块上测试了相同的代码,并且能够下载大约 50KB 的文件。
我不确定是我使用的内存或库的问题还是 ESP32 的限制。我附上代码sn-p以及我用过的内存分区,请指导。
访问文件下载链接后 ESP32 重启时出错:
abort() 在核心 1 上的 PC 0x401d844b 被调用
回溯:0x40092b60:0x3ffcf8e0 0x40092d91:0x3ffcf900 0x401d844b:0x3ffcf920 0x401d8492:0x3ffcf940 0x401bf359:0x3ffcf960 0x401bf0dc:0x3ffcf980 0x400fa67e:0x3ffcf9a0 0x400fa75a:0x3ffcf9d0 0x400e62b9:0x3ffcf9f0 0x400d23e4:0x3ffcfa20 0x400d27e3:0x3ffcfa40 0x400d2ed7:0x3ffcfa70 0x400d35f1:0x3ffcfa90 0x400e9151:0x3ffcfb10 0x4008f275:0x3ffcfb30
正在重新启动...
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 模式:DIO,时钟 div:2 负载:0x3fff0018,长度:4 负载:0x3fff001c,长度:1044 加载:0x40078000,长度:8896 加载:0x40080400,长度:5828 条目 0x400806ac
代码 sn-p:
void downloadfile() //function to download file on mobile App
delay(500);
do
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->stop();
if(!SPIFFS.begin())
Serial.println("An Error has occurred while mounting SPIFFS");
return;
WiFi.mode(WIFI_AP);
delay(100);
Serial.print("Setting soft-AP ... ");
Serial.println(WiFi.softAP("ESP32","123456789") ? "Ready" : "Failed!");
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
delay(100);
// send a file when /download is requested
server.on("/download", HTTP_ANY, [](AsyncWebServerRequest *request)
request->send(SPIFFS, "/file1.json", "text/plain", true);
);
server.on("/finisheddownload", HTTP_GET, [](AsyncWebServerRequest *request)
logfile.del_file();
request->send(200, "text/html", "Download complete response");
delay(500);
Actual_filexist = 0;
WiFi.softAPdisconnect(true);
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
delay(500);
);
server.begin();
delay(500);
while(Actual_filexist == 1);
内存分区: #name 类型子类型偏移大小标志 nvs 数据 nvs 0x9000 0x7000 app0 应用程序 ota_0 0x10000 0x2A0000 eeprom 数据 0x99 0x2F0000 0x1A8CE0 spiffs 数据 spiffs 0x498CE0 0xA7D8C0
内存使用: RAM:[==] 19.9%(从 327680 字节使用 65292 字节) Flash:[======] 60.1%(从 2752512 字节中使用了 1654361 字节)
谢谢……
【问题讨论】:
【参考方案1】:您正在使用ESPAsyncWebServer。它的文档明确指出,您不应调用delay()
或yield()
或任何在来自Web 服务器(Important things to remember)的回调中调用它们的函数。您在/finisheddownload
处理程序中调用了两次delay()
。
您还在处理程序返回之前在处理程序中调用WiFi.softAPdisconnect()
,这意味着您在回调返回之前以及可能在将响应发送到浏览器之前关闭了 Wifi。在回调中这样做是不安全的。
您需要在来自网络服务器的回调中做尽可能少的事情。重写该处理程序以设置loop()
将检查的标志,以便它所做的所有工作除了对request->send()
的调用实际上都在loop()
中完成。
【讨论】:
嗨@romkey,谢谢你的cmets...正如建议的那样,我已经删除了所有延迟并从网络服务器中删除了“WiFi.softAPdisconnect()”和回调中的其他内容,但仍然面临以下问题重新开始。一旦我从浏览器“192.168.4.1/download”或“192.168.4.1/finisheddownload”中ping任何链接,模块就会重新启动,显示此“dhcps:send_offer>>udp_sendto result 0 abort() was called at PC 0x401d8333 on core 1" 在串行终端上。请指导以上是关于使用 ESP32 网络服务器下载文件时面临问题的主要内容,如果未能解决你的问题,请参考以下文章
启明云端分享|ESP32在开发环境时,常遇到的问题答疑(FAQ)
Arduino ESP32 获取网络数据(HTTP GET方式)