rest - esp32 休息分块响应
问题描述
我试图了解 esp32 的真正 wifi 速度能力,所以我使用公共库创建了一个简单的例程
void speedTest(AsyncWebServerRequest *request)
{
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
}
但是当我发出 GET 请求时,电路板会自行重置,并且在串行监视器中我看到以下日志:
rst:0x1 (POWERON_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
mode:DIO,clock div: 2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
E (17770) task_wdt:任务看门狗被触发。以下任务没有及时重置看门狗:
E (17770) task_wdt: - async_tcp (CPU 0/1)
E (17770) task_wdt: 当前运行的任务:
E (17770) task_wdt: CPU 0:
IDLE0 E (17770) task_wdt : CPU 1: loopTask
E (17770) task_wdt: 中止。
abort() 在核心 0 上的 PC 0x40131b44 被调用
我也尝试减小文件大小并且下载正常,但对我的目的来说是无用的。有人已经遇到并解决了这个问题?我不是一个真正的 lambda 爱好者,或者一个更可定制的不同库,如果可能的话,我不想通过套接字重新实现所有 http 协议。 提前感谢您的帮助。
完整代码:
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
AsyncWebServer server(80);
const char* ssid = "testSpeed";
const char* psw = "12345678";
void notFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "Not found");
}
void speedTest(AsyncWebServerRequest *request)
{
#if 1
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
#endif
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, psw);
WiFi.softAPConfig(local_ip, gateway, subnet);
server.on("/stream", HTTP_GET, speedTest);
server.onNotFound(notFound);
server.begin();
}
void loop() {
}
解决方案
看起来 AsyncWebServer 的实现不适用于长时间运行的事务,因为它从不重置任务看门狗。作为一种解决方法,您可以将看门狗超时增加到其最大限制 60 秒或完全禁用它。它由 sdkconfig 中的以下选项控制:
CONFIG_ESP_TASK_WDT=y # Task Watchdog is enabled
CONFIG_ESP_TASK_WDT_PANIC=y # Panic (reset) is invoked on timeout
CONFIG_ESP_TASK_WDT_TIMEOUT_S=30 # Timeout in seconds
更改它们的正常方法是运行idf.py menuconfig
(它们出现在“组件配置”、“通用 ESP 相关”下),但您可以直接更新文件“sdkconfig”。
完成实验后撤消这些更改,保持启用任务看门狗通常是个好主意。
推荐阅读
- r - 我的 for 循环中不断出现语法错误?
- .net-core - rabbit mq 在同一个注册中添加多个队列
- react-native - 当我尝试删除图像时反应原生 Expo 我有错误
- r - 如何加快我的 lapply 迭代列表以在 R 中的数据框中搜索值?
- python - 如何组合和比较两个笔记本的结果
- python - Selenium 得到大于 x 的 img
- sql - 如何从一列的不同行中获取值以分隔列
- amazon-web-services - SQS 是否允许在重复数据删除期间重试事件?
- php - PHP PDO 连接在 GoDaddy 连接字符串上显示 2 个 @ 符号
- excel - Excel VBA - 从单元格读取时,代码会将小数转换为整数