C 串行协议的状态机
我正在用c编写一个串行协议的状态机。我的数据包格式如下所示 delim0接口命令\u H命令\u L长度\u H长度\u L有效负载校验和delim1 编辑:我的问题是如何编写一个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
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*)缓冲区代码>由于提到的填充/对齐问题,此代码可能根本无法在许多实际处理器上工作。很可能您必须编写序列化/反序列化例程。