c++ - 导致 ESP32 随机停止并触发看门狗定时器重启的串行数据包
问题描述
我正在使用 ESP32-Arduino 在 RTOS 任务中连续接收串行数据(Serial1 上的 2400 波特)。该任务使用状态机测试某个字节序列,并在设置有效数据包标志之前进行数据包验证。
有时,当我有太多数据进入时,系统会停止并触发看门狗重启。
我身上没有调试器,所以我只能依靠检查串行监视器(Serial)并放置打印语句。
我认为也许缓冲区已满,我没有足够的时间进行服务,但我不确定。
我试图减少 RTOS 任务中的代码,让后处理在主循环中完成。我想我可以更多地完成任务,但我没有进一步尝试。
我也尝试过增加或减少任务的频率,但似乎没有什么不同。
这是我的代码:
void readSerial(void *pvParameters)
{
for (;;)
{
// Serial.print("chars avail: ");
while (Serial1.available())
{
char ch = Serial1.read();
switch (nextSerialRecieveState)
{
case IDLE:
case HEADER_0:
default:
rxByteIndex = 0;
checkSum = 0;
if (ch == 0x5A)
{
nextSerialRecieveState = HEADER_1;
}
else
{
nextSerialRecieveState = IDLE;
}
break;
case HEADER_1:
if (ch == 0x54)
{
nextSerialRecieveState = PACKET_LENGTH;
}
else
{
nextSerialRecieveState = IDLE;
}
break;
case PACKET_LENGTH:
case CHECKSUM_UPPER:
checkSumUpperByte = ch;
nextSerialRecieveState = CHECKSUM_LOWER;
break;
case CHECKSUM_LOWER:
checkSumLowerByte = ch;
if ((((checkSumUpperByte << 8) + checkSumLowerByte) == checkSum))
{
serialPrintBuffer();
Serial.print("VALID PACKET FROM ");
Serial.print(SOURCE_BYTE_0, HEX);
Serial.print(":");
Serial.print(SOURCE_BYTE_1, HEX);
Serial.print(":");
Serial.println(SOURCE_BYTE_2, HEX);
validPacketFlag = 1;
}
}
nextSerialRecieveState = IDLE;
break;
}
//lastByteReceivedTime = millis();
}
delay(10);
}
}
不是为什么我对这项任务有一些基本的误解。
解决方案
我认为也许缓冲区已满,我没有足够的时间进行服务,但我不确定。
那么当输入缓冲区(几乎)满时会发生什么?是否有协议向远程发射器发出不发射信号?如果没有,缓冲区可能会溢出,然后消息框架可能会变得混乱,这可能会混淆代码的逻辑。
没有调试器:至少,检查代码本身中的缓冲区溢出,并使其为人所知。如果有,那么代码无论如何都没用。
我试图减少 RTOS 任务中的代码,让后处理在主循环中完成。我想我可以更多地完成任务,但我没有进一步尝试。
完成那个任务。作为一般规则,在 RTOS 内尽可能少做。
我也尝试过增加或减少任务的频率,但似乎没有什么不同。
这不会影响数据到达的速率。首先要做的事情:确定是否存在缓冲区溢出。
推荐阅读
- excel - Excel Mac OS libc.dylib popen 不返回数据
- java - 如何通过按返回按钮退出视频全屏
- asp.net - 视图状态解密的密钥如何与客户端共享?
- flex-lexer - Flex 词法分析器未按预期运行
- azure-cosmosdb - Function App中的Azure Service Bus Topic触发器-限制读取的消息数
- java - 如何使用java快速将记录插入cassandra表
- android - Timber 中有没有办法在日志中显示父方法名称 android
- javascript - FirebaseError:[code=resource-exhausted]:写入流已用尽最大允许排队写入
- javascript - 为什么按住一个键会写一个字母,口吃一秒钟,然后继续向该键发送垃圾邮件?
- python - 如何更新字典以添加到 Python 中的列表