Debug Serial para programa resetar o buffer quando houver tamanhos errados na mensagem

Dependencies:   pulga-lorawan-drv PingPong-P2P-ClickButtonToWork-SX1272

Revision:
7:37dc9ce68914
Child:
12:d0ca7c3c8962
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serial.cpp	Fri Mar 19 20:26:32 2021 +0000
@@ -0,0 +1,162 @@
+#include "serial.h"
+
+RawSerial pc(P0_28, P0_25);
+
+static char circ_buffer[512];
+static int rd_index = 0;
+static int wr_index = 0;
+static int buf_len = 0;
+
+void SerialRx(void)
+{
+    char msg[256];
+    int msg_incompleta;
+    int msg_len;
+    int i, j;
+    
+    /// Execucao do comando nao deve fazer parte da recepcao de dados serial!
+    /// Deve existir separacao entre camada fisica, protocolo de baixo nivel
+    /// e de alto nivel.
+
+    /// 1) Vamos implementar a parte de recepcao serial com buffer circular.
+    /// 2) Vamos implementar rejeicao de ruido.
+    /// 3) Interpretamos, executamos ou descartamos comandos.
+
+     /// Recepcao serial
+    while(pc.readable())
+    {
+        /// buffer circular cheio entao sai do loop
+        if (buf_len >= sizeof(circ_buffer)) {
+            break;
+        }
+        circ_buffer[wr_index] = pc.getc();
+
+        buf_len++;
+        wr_index++;
+
+        if (wr_index >= sizeof(circ_buffer)) {
+            wr_index = 0;
+        }
+    }
+
+    /// Vamos retirar todos os caracteres invalidos antes do comando
+    /// Um comando sempre inicia com '<'
+    while(buf_len > 0)
+    {
+        if (circ_buffer[rd_index] == '<') {
+            break; /// rd_index fica com o indice do inicio da mensagem
+        }
+
+        buf_len--;
+        rd_index++;
+
+        if (rd_index >= sizeof(circ_buffer)) {
+            rd_index = 0;
+        }
+    }
+
+    /// Se ficou vazio, tudo era ruido, limpa todas as variaveis globais e sai
+    if (buf_len <= 0)
+    {
+        //printf("ruido\n");
+        rd_index = 0;
+        wr_index = 0;
+        buf_len = 0;
+        pc.attach(&serial_post_to_queue, RawSerial::RxIrq);
+        return;
+    }
+
+    /// Agora vamos verificar se a mensagem esta completa.
+    /// Procura o final (terminada em '>').
+    /// Nao altero rd_index!!
+    i = 0;
+    j = rd_index;
+    msg_incompleta = 1;
+
+    while (i < buf_len)
+    {
+        if (circ_buffer[j] == '>')
+        {
+            ///encontrou final de cmd
+            msg_incompleta = 0;
+            break;
+        }
+        j++;
+        i++;
+
+        if (j >= sizeof(circ_buffer)) {
+            j = 0;
+        }
+    }
+
+    /// Se a mensagem esta incompleta, deixa para a proxima vez.
+    /// Mas aqui tem uma sacada, se o buffer circular estiver cheio,
+    /// nunca receberei o final... Entao o codigo nao receberia nunca mais.
+    /// Para evitar o travamento permanente, limpa tudo nesse caso.
+    /// <------------ Isso causava o erro !!!!!!
+    if (msg_incompleta)
+    {
+        if (buf_len >= sizeof(circ_buffer))
+        {
+            rd_index = 0;
+            wr_index = 0;
+            buf_len = 0;
+        }
+        pc.attach(&serial_post_to_queue, RawSerial::RxIrq);
+        return;
+    }
+
+    /// Finalmente copio a msg
+    msg_len = 0;
+    while(buf_len > 0)
+    {
+        if (msg_len < sizeof(msg))
+        {
+            msg[msg_len] = circ_buffer[rd_index];
+            msg_len++;
+        }
+        else
+        {
+            /// A mensagem esta errada, grande demais.
+            msg_len = 0;
+            break;
+        }
+
+        if (circ_buffer[rd_index] == '>')
+        {
+            ///encontrou final de cmd
+            break;
+        }
+
+        buf_len--;
+        rd_index++;
+
+        if (rd_index >= sizeof(circ_buffer)) {
+            rd_index = 0;
+        }
+    }
+
+    /// Agora posso limpar todo o buffer circular
+    rd_index = 0;
+    wr_index = 0;
+    buf_len = 0;
+
+    /// A mensagem foi truncada entao sai.
+    if (msg_len == 0) {
+        pc.attach(&serial_post_to_queue, RawSerial::RxIrq);
+        return;
+    }
+
+    /// Troco o '>' do final por null
+    msg[msg_len - 1] = '\0';
+    
+    SerialCommandRun(msg);
+    
+    pc.attach(&serial_post_to_queue, RawSerial::RxIrq);
+    return;
+}
+
+
+void PrintDebugMsg(char *msg){
+    pc.printf(msg);
+}
\ No newline at end of file