ESP32串行流冻结

发布于 2025-01-22 09:53:08 字数 2496 浏览 3 评论 0原文

我有一个主设备,ESP32充当从属,直接通过RX/TX电缆在UART上进行通信。我创建了一个任务,每50 ms检查串行流并解析数据。我的问题是,串行流似乎是随机的,仅在主人或从属重新启动时才重新启动。

任务看起来像这样:

void TaskListen_UART(void *pvParameters)
{
  while (true)
  {
    if (readSerialIn()) 
    {
      slaveRunCommand(serialData.command); // Execute received commmand
    }
    vTaskDelay(50 / portTICK_PERIOD_MS);
  }
}

它通过readserialin()检查串行流,该流如下:

bool readSerialIn()
{
    if (UART.available() > 0) // Check if the Serial port received data
    {
        serialData.clearStruct(); // Clear previously saved data
        if (UART.find(0x2A)) // Find "*" // Find starting delimiter 
        {
            serialData.length = UART.read(); // Read length
            if (serialData.length > BYTE_BUFFER_LEN)
            {
                writeSerialNACK(); // Write NACK if length seems incorrect 
                return false;
            }
            Serial.printf(("Message length: %d\n"), serialData.length);
            serialData.checksum = UART.read(); // Read Checksum
            Serial.printf(("Checksum:  %d\n"), serialData.checksum);
            if (parseBuffer(serialData.length)) // Parse the data
            {
                if (serialData.checkSum()) // If the checksum passes
                {
                    serialData.assignBuffer(); // Save the parsed data to the global buffer
                    return true;
                }
                else
                {
                    writeSerialNACK();
                    return false;
                }
            }
            else
                false;
        }
        else
            return false;
    }
}

parsebuffer()函数实际上读取流并将其解析为他们的价值观在奴隶上。我试图以最大的安全方式编写它,但它仍然没有清除我的问题。

bool parseBuffer(uint8_t bufferLength)
{
    uint8_t bufferPos = 0;
    bool uartDetectFlag = false;
    while (UART.available() > 0)
    {
        uartDetectFlag = true;
        if (bufferPos < bufferLength)
        {
            serialData.serialBuffer[bufferPos] = UART.read();
        }
        bufferPos++;
    }
    if (uartDetectFlag)
        return true;
    else
        return false;
}

起初,我怀疑ESP试图访问不存在的内存中的一个块。但是,我注意到它不会像正常情况那样重置自己,如果是这种情况,我尝试以非阻滞方式编写parsebuffer。我还尝试将任务延迟增加到100 ms,这降低了阻塞的频率,但在速度方面不足。无论如何,它冻结了,并且(我认为)这是由串行流的大量数据引起的。

I have a master device and ESP32 acting as a slave, communicating directly over UART with RX/TX cables. I've created a task that checks the serial stream every 50 ms and parses the data. My problem is that the serial stream freezes up, seemingly randomly, and only restarts if the master or the slave are restarted.

The task looks as such:

void TaskListen_UART(void *pvParameters)
{
  while (true)
  {
    if (readSerialIn()) 
    {
      slaveRunCommand(serialData.command); // Execute received commmand
    }
    vTaskDelay(50 / portTICK_PERIOD_MS);
  }
}

It checks the serial stream through readSerialIn() which looks like the following:

bool readSerialIn()
{
    if (UART.available() > 0) // Check if the Serial port received data
    {
        serialData.clearStruct(); // Clear previously saved data
        if (UART.find(0x2A)) // Find "*" // Find starting delimiter 
        {
            serialData.length = UART.read(); // Read length
            if (serialData.length > BYTE_BUFFER_LEN)
            {
                writeSerialNACK(); // Write NACK if length seems incorrect 
                return false;
            }
            Serial.printf(("Message length: %d\n"), serialData.length);
            serialData.checksum = UART.read(); // Read Checksum
            Serial.printf(("Checksum:  %d\n"), serialData.checksum);
            if (parseBuffer(serialData.length)) // Parse the data
            {
                if (serialData.checkSum()) // If the checksum passes
                {
                    serialData.assignBuffer(); // Save the parsed data to the global buffer
                    return true;
                }
                else
                {
                    writeSerialNACK();
                    return false;
                }
            }
            else
                false;
        }
        else
            return false;
    }
}

The parseBuffer() function is what actually reads the stream and parses it into their according values on the slave. I tried to write it in the most fail-safe fashion, but it still hasn't cleared up my issue.

bool parseBuffer(uint8_t bufferLength)
{
    uint8_t bufferPos = 0;
    bool uartDetectFlag = false;
    while (UART.available() > 0)
    {
        uartDetectFlag = true;
        if (bufferPos < bufferLength)
        {
            serialData.serialBuffer[bufferPos] = UART.read();
        }
        bufferPos++;
    }
    if (uartDetectFlag)
        return true;
    else
        return false;
}

At first I was suspicious that the ESP was trying to access a block in memory that doesn't exist. I noticed however that it doesn't reset itself like it normally would if that were the case, and I tried writing parseBuffer in a non-blocking manner. I also tried increasing the task delay to 100 ms, which reduced the frequency of the blocking but did not suffice in terms of speed. Regardless, it freezes up and (I think) it's caused by a large flow of data through the serial stream.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文