C 串行协议的状态机

C 串行协议的状态机,c,serial-port,uart,state-machine,C,Serial Port,Uart,State Machine,我正在用c编写一个串行协议的状态机。我的数据包格式如下所示 delim0接口命令\u H命令\u L长度\u H长度\u L有效负载校验和delim1 编辑:我的问题是如何编写一个c代码来使用这个状态机计算有效负载和校验和 我不熟悉这个话题,如果我犯了一些简单的错误,请原谅 switch (dev_int_state) { case UART_INT_STATE_IDLE: if (c == '<') { // Delim

我正在用c编写一个串行协议的状态机。我的数据包格式如下所示

delim0接口命令\u H命令\u L长度\u H长度\u L有效负载校验和delim1

编辑:我的问题是如何编写一个c代码来使用这个状态机计算有效负载和校验和

我不熟悉这个话题,如果我犯了一些简单的错误,请原谅

switch (dev_int_state) {
          case UART_INT_STATE_IDLE:
                if (c == '<') {         // Delim0 = 0x3C

                dev_int_state = UART_INT_STATE_INTERFACE;
  }
  break;
          case UART_INT_STATE_INTERFACE:
               if (c == 0x00) {         //Generic Commands = 0x00

               dev_int_state = UART_INT_STATE_REQ_INTERFACE_SUPPORTED;
  }
  break;
           case UART_INT_STATE_REQ_INTERFACE_SUPPORTED:
                if (c == 0x00) {        // REQ_INTERFACE_SUPPORTED = 0x00

               dev_int_state = UART_INT_STATE_GET_PROTOCOLHH;
  }
  break;
           case UART_INT_STATE_GET_PROTOCOLHH:
                if (c == 0x00) {          // GET_PROTOCOL = 0x00

               dev_int_state = UART_INT_STATE_GET_PROTOCOLHL;
  }
 break;
           case UART_INT_STATE_GET_PROTOCOLHL:
                if (c == 0x0B) {           // GET_PROTOCOL_RESPONSE = 0x000B

               dev_int_state = UART_INT_STATE_LENGTHH;
  }
 break;
          case UART_INT_STATE_LENGTHH:
               if (c ==0x04) {

          dev_int_state = UART_INT_STATE_LENGTHL;          // LENGHT = 4 bytes
  }
 break;
          case UART_INT_STATE_LENGTHL:
          if (c == 0x00) {



          dev_int_state = UART_INT_STATE_PAYLOAD;
  }
 break;
          case UART_INT_STATE_PAYLOAD:


                       {        //--- i want to store the payload in this state

                                      }

          case UART_INT_STATE_CHECKSUM:

{
              size = 0;
              for (unsigned i = 0; i< headerLength-1; i++) { /* i have computed checksum but not sure about it */
                  size += headerBuffer[i];
              }

              dev_int_state = UART_INT_STATE_DELIM1;
}
 break;

               dev_int_state = UART_INT_STATE_DELIM1;
 }
 break;
         case UART_INT_STATE_DELIM1:
              if (c == '>') {





      }
       break;
  default:
       break;
}
开关(dev\u int\u状态){
情况UART\u INT\u STATE\u IDLE:
如果(c=''){
}
打破
违约:
打破
}
  • 继续将收到的字符
    c
    保存到缓冲区中,并增加索引
    buffer[index++]=c
  • 一旦到达
    案例UART\u INT\u状态\u校验和:
    如果您有一个简单的
    总和
    校验和,则在缓冲区中添加所有字节(校验和字节除外)。然后将其与接收到的校验和字节进行比较。这实际上取决于协议的校验和类型
  • 注意:您有时将
    c
    用作1字节,有时用作2字节。如果c是一个字符,那么它将始终是1字节。如果您首先捕获整个数据包,然后将其转换为协议类型的结构并检查适当的值,可能会更容易

    例如:

    typedef struct uart_protocol_t
    {
        uint8_t delim0;
        uint8_t interface;
        union {
            struct {
                uint8_t command_H;
                uint8_t command_L;
            }cmd_bytes;
            uint16_t command;
        }cmd_union;
        union {
            struct {
                uint8_t length_H;
                uint8_t length_L;
            }len_bytes;
            uint16_t length;
        }len_union;
        uint8_t payload;
        uint8_t checksum;
        uint8_t delim1;
    }uart_protocol_t;
    
    那就投吧

    uart_protocol_t *p_proto = (uart_protocol_t *)buffer;
    

    “我的问题是如何使用状态机计算有效负载和校验和。”你这是什么意思?这个问题必须精确,否则就无法回答。请回答,并且只有一个明确的问题。您需要按照给定协议的规定计算有效负载和校验和。您希望internet上的一些随机人员如何告诉您特定的定制UART协议是如何构建的?注意:您的所有状态都只有一个传出状态。我认为您需要时不时地返回初始状态(出错时)以重新同步。。。并添加更多状态来处理4字节长度的字段和校验和,以及一对状态来处理可变长度的有效负载(init和后续)。您不必更改每个字节的状态-可变长度有效负载状态不需要每个字节的状态@Lundin我已经计算了UART协议的有效负载和校验和,但我不确定如何为它编写语法。所以我想知道使用状态机计算有效负载和校验和的语法。像这样的联合通常不是一个好主意,因为它们依赖于CPU的持久性,而不是数据协议的持久性。还请注意,此结构可能会在结构内部的任何点引入填充。
    uart_protocol_t*p_proto=(uart_protocol_t*)缓冲区由于提到的填充/对齐问题,此代码可能根本无法在许多实际处理器上工作。很可能您必须编写序列化/反序列化例程。