首页 > 解决方案 > 导致 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);
    }
}

不是为什么我对这项任务有一些基本的误解。

标签: c++arduinoesp32

解决方案


我认为也许缓冲区已满,我没有足够的时间进行服务,但我不确定。

那么当输入缓冲区(几乎)满时会发生什么?是否有协议向远程发射器发出不发射信号?如果没有,缓冲区可能会溢出,然后消息框架可能会变得混乱,这可能会混淆代码的逻辑。

没有调试器:至少,检查代码本身中的缓冲区溢出,并使其为人所知。如果有,那么代码无论如何都没用。

我试图减少 RTOS 任务中的代码,让后处理在主循环中完成。我想我可以更多地完成任务,但我没有进一步尝试。

完成那个任务。作为一般规则,在 RTOS 内尽可能少做。

我也尝试过增加或减少任务的频率,但似乎没有什么不同。

这不会影响数据到达的速率。首先要做的事情:确定是否存在缓冲区溢出。


推荐阅读