简体   繁体   English

导致ESP32随机停止并触发看门狗定时器重启的串行数据包

[英]Serial packets causing ESP32 to randomly halt and trigger watchdog timer reboot

I'm using the ESP32-Arduino to continuously receive serial data (2400 baud on Serial1) in an RTOS task. 我正在使用ESP32-Arduino在RTOS任务中连续接收串行数据(Serial1上为2400波特)。 The task tests for a certain byte sequence using a state machine and does packet validation before setting a valid packet flag. 该任务使用状态机测试某个字节序列,并在设置有效的数据包标志之前进行数据包验证。

Occasionally, when I have too much data coming in, the system will halt and trigger a watchdog reboot. 有时,当我收到太多数据时,系统将停止运行并触发看门狗重启。

I don't have a debugger on me so I can only rely on checking the serial monitor (Serial) and put print statements. 我没有调试器,所以我只能依靠检查串行监视器(Serial)并放入打印语句。

I thought that perhaps the buffer was full and I didn't get enough time to service is but I'm not sure. 我以为缓冲区可能已满,我没有足够的时间来服务,但是我不确定。

I've tried to reduce the code in the RTOS task and let the post processing be done in the main loop. 我试图减少RTOS任务中的代码,并让后处理在主循环中完成。 I guess I could trip the task even more but I haven't tried further. 我想我可以进一步完成任务,但是我没有再尝试。

I've also tried to both increase or decrease the frequency of the task and doesn't seem to make a difference. 我也尝试过增加或减少任务的频率,但似乎没有什么不同。

Here's my code: 这是我的代码:


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);
    }
}

not why is there's some fundamental misunderstanding I have about this task. 不是为什么我对此任务有一些根本的误解。

I thought that perhaps the buffer was full and I didn't get enough time to service is but I'm not sure. 我以为缓冲区可能已满,我没有足够的时间来服务,但是我不确定。

So what happens when the input buffer is (nearly) full? 那么,当输入缓冲区(几乎)已满时会发生什么? Is there a protocol to signal the remote transmitter not to transmit? 是否有协议通知远程发送器不发送信号? If not, the buffer may overrun and then the message framing can get messed up, which can confuse the logic of your code. 否则,缓冲区可能会溢出,然后消息框架可能会混乱,这可能会使代码的逻辑混乱。

No debugger: at the very least, check for buffer overrun within the code itself, and make it known. 没有调试器:至少,请检查代码本身中的缓冲区溢出,并使其知道。 If there is, the code is useless anyway. 如果有的话,该代码还是无用的。

I've tried to reduce the code in the RTOS task and let the post processing be done in the main loop. 我试图减少RTOS任务中的代码,并让后处理在主循环中完成。 I guess I could trip the task even more but I haven't tried further. 我想我可以进一步完成任务,但是我没有再尝试。

Complete that task. 完成该任务。 As a general rule, do as little as possible within the RTOS. 通常,在RTOS中尽量少做。

I've also tried to both increase or decrease the frequency of the task and doesn't seem to make a difference. 我也尝试过增加或减少任务的频率,但似乎没有什么不同。

That won't affect the rate the data is arriving. 这不会影响数据到达的速度。 First things first: establish if there is buffer overrun. 首先,要确定是否存在缓冲区溢出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM