Linux串口断帧处理

报文格式
1 Byte
4 Byte
N Byte
4 Byte
1 Byte
0x02
报文长度
报文
CRC16
0x03

1. 每条报文以 STX(0x02)起始符开始,以 ETX(0x03)终止符结束。
2. 报文正文长度采用 4 字节的 10 进制字符串标识,如报文正文长度为十
进制 298,则相应的字段为"0298"。
3. 报文正文采用 json 字符串形式进行描述。
4. 报文正文后跟报文正文的 CRC16 校验码,CRC16 校验码采用 4 字节的
16 进制字符串标识,如 CRC16 校验码为 0x89 0xA9,则相应的字段为为"89A9"。
5. 串口数据采用 CRC16(XMODEM)算法校验,举例:校验报文原文"abcdefg",
CRC16 结果为 0x7658。
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define START_BYTE 0x02
#define END_BYTE 0x03

static int times = 0;
int my_read(uint8_t *data, uint32_t max_len)
{
   char *a="\x02\x30\x30\x37\x37\x7B\x22\x64\x61\x74\x61\x22\x3A\x7B\x22\x61";
   char *b="\x63\x74\x69\x6F\x6E\x22\x3A\x31\x7D\x2C\x22\x63\x6D\x64\x22\x3A\x22\x43\x32\x22\x2C\x22\x74\x69\x6D\x65\x22\x3A\x22\x31\x36\x39\x37\x31\x31\x30\x36\x39\x39\x30\x38\x33\x22\x2C\x22\x6D\x73\x67\x5F\x69\x64\x22\x3A\x22\x31\x36\x39\x37\x31\x31\x30\x36\x39\x39\x22";
   char *c="\x7D\x44\x42\x46\x32\x03";
   
   size_t bytesRead = 0;

	if(times==0)
	{
		bytesRead = 16;
		memcpy(data, a, 16);
		times++;
	}
	else if(times==1)
	{
		bytesRead = 65;
		memcpy(data, b, bytesRead);
		times++;
	}
	else
	{
		times = 0;
		bytesRead = 6;
		memcpy(data, c, bytesRead);
	}
	
	return bytesRead;
	
}

int my_recv(uint8_t *recv_data, uint32_t *recv_len)
{
    // 从串口接收数据
    uint8_t buffer[1024] = {0};
	*recv_len = 0;
    size_t bytesRead = 0;
		
	while (true) {

		bytesRead = my_read(buffer, sizeof(buffer));
		// 处理接收到的数据
		if (bytesRead <= 0) 
		{
			break;
		}
		
		printf("bytesRead=%ld\n",bytesRead);
		if(buffer[0] == START_BYTE)
		{
			*recv_len = bytesRead;
			memcpy(recv_data, buffer, bytesRead);
		}
		else
		{
			if((*recv_len+bytesRead)> sizeof(buffer))
			{
				*recv_len = 0;
				break;
			}
			memcpy(recv_data+*recv_len, buffer, bytesRead);
			*recv_len += bytesRead;
		}

		if(recv_data[0] != START_BYTE) 
		{
				*recv_len = 0;
				break;
		}
		
		if(recv_data[*recv_len-1] == END_BYTE)
		{
			return *recv_len;
		}
	} 
	
	return -1;
}

int main() {
   uint8_t frame[1024];
   int frame_len;
   memset(frame, 0, sizeof(frame));
 
   printf("len=%d\n", my_recv(frame, &frame_len));
   
   if(frame_len > 6)
   {
		// 打印报文数据
		printf("Received frame: ");
		for (size_t i = 0; i < frame_len-10; i++) {
			printf("%02x ", frame[i+5]);
		}
		printf("\n");
   }
   
   return 0;
}

你可能感兴趣的:(linux)