接收协议、动态数组存储、提供两种解析方式

只需要输入帧头、帧长度、校验起始字节、结束字节、定义帧字段结构体,解析一帧数据。linux,keil开发通用!!!!

ParseProtocol.h

#ifndef _BSB_HEADER
#define _BSB_HEADER
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define ERRORLOG(msg)                                       \
	do                                                      \
	{                                                       \
		printf("%s:%s:%d\n", __FILE__, __func__, __LINE__); \
		perror(msg);                                        \
	} while (0);

/*

function: 实现动态数组存储协议帧解析协议
author: mass
day:2024-11-19

*/
#define FRAME_HEADER 0x90EB // 帧头
#define FRAME_SIZE 145       // 每帧数据的大小
#define CHECK_BEGIN 0       //校验区起始字节
#define CHECK_END 89		//校验区结束字节,即校验4-78字节
#define CHECK_SUM_BEGIN 90  //校验字段起始字节(无符号16位校验和)

#define INITIAL_CAPACITY 256 // 初始容量,不能为0
// 动态数组结构
typedef struct
{
    char *buffer;    // 指向动态分配的数组
    size_t size;     // 数组中当前元素的数量
    size_t capacity; // 数组的总容量
} DynamicArray;
void initArray(DynamicArray *a);
void freeArray(DynamicArray *a);
void ensureCapacity(DynamicArray *a, size_t additionalSize);
void addData(DynamicArray *a, const char *data, size_t dataSize);
void removeFrame(DynamicArray *a, size_t frameSize);
int check_sum(char *buf);
/********************************bsb******************************************************************/
typedef signed char bsb_int8_t;
typedef unsigned char bsb_uint8_t;
typedef short bsb_int16_t;
typedef unsigned short bsb_uint16_t;
typedef int bsb_int32_t;
typedef unsigned int bsb_uint32_t;
typedef long long bsb_int64_t;
typedef unsigned long long bsb_uint64_t;

/* Private data structure */
typedef struct bsb
{
	unsigned char *buf;
	unsigned char *ptr;
	unsigned char *end;
} BSB;
// 注意:这里使用unsigned char指向char类型的buff存、取数据时并不会出错,因为bit位值没变。
// 例:
// 无论怎么强转,内存中的位数据保持不会改变,x有无符号均可以,初始化的buf同样道理
//  unsigned int a=-8;
//  printf("%u\n",a);//4294967288
//  int b=(unsigned int)-8;
//  printf("%d\n",b);//-8
//  初始化
#define BSB_INIT(b, buffer, size)                     \
	do                                                \
	{                                                 \
		(b).buf = (unsigned char *)buffer;            \
		(b).ptr = (unsigned char *)buffer;            \
		int s = (int)size;                            \
		if ((buffer == NULL) || (s < 0))              \
			(b).end = 0;                              \
		else                                          \
			(b).end = (unsigned char *)buffer + size; \
	} while (0)
// 错误处理
#define BSB_SET_ERROR(b) ((b).end = NULL)
// 已写/取的buf长度
#define BSB_LENGTH(b) ((b).ptr - (b).buf)
// 剩余长度
#define BSB_REMAINING(b) ((b).end ? (b).end - (b).ptr : 0)
#define BSB_WORK_PTR(b) ((b).ptr)

/************************************************从bsb.buf取字节********************************************/

#define BSB_IMPORT_u08(b, x)                   \
	do                                         \
	{                                          \
		if ((b).ptr && (b).ptr + 1 <= (b).end) \
		{                                      \
			x = *(((b).ptr)++);                \
		}                                      \
		else                                   \
			BSB_SET_ERROR(b);                  \
	} while (0)

#define BSB_IMPORT_u16(b, x)                                                      \
	do                                                                            \
	{                                                                             \
		if ((b).ptr && (b).ptr + 2 <= (b).end)                                    \
		{                                                                         \
			x = ((bsb_uint16_t)((b).ptr)[0]) << 8 | ((bsb_uint16_t)((b).ptr)[1]); \
			(b).ptr += 2;                                                         \
		}                                                                         \
		else                                                                      \
			BSB_SET_ERROR(b);                                                     \
	} while (0)

#define BSB_IMPORT_u24(b, x)                                                             \
	do                                                                                   \
	{                                                                                    \
		if ((b).ptr && (b).ptr + 3 <= (b).end)                                           \
		{                                                                                \
			x = ((bsb_uint32_t)((b).ptr)[0]) << 16 | ((bsb_uint32_t)((b).ptr)[1]) << 8 | \
				((bsb_uint32_t)((b).ptr)[2]);                                            \
			(b).ptr += 3;                                                                \
		}                                                                                \
		else                                                                             \
			BSB_SET_ERROR(b);                                                            \
	} while (0)

#define BSB_IMPORT_u32(b, x)                                                              \
	do                                                                                    \
	{                                                                                     \
		if ((b).ptr && (b).ptr + 4 <= (b).end)                                            \
		{                                                                                 \
			x = ((bsb_uint32_t)((b).ptr)[0]) << 24 | ((bsb_uint32_t)((b).ptr)[1]) << 16 | \
				((bsb_uint32_t)((b).ptr)[2]) << 8 | ((bsb_uint32_t)((b).ptr)[3]);         \
			(b).ptr += 4;                                                                 \
		}                                                                                 \
		else                                                                              \
			BSB_SET_ERROR(b);                                                             \
	} while (0)

#define BSB_IMPORT_u64(b, x)                                                              \
	do                                                                                    \
	{                                                                                     \
		if ((b).ptr && (b).ptr + 8 <= (b).end)                                            \
		{                                                                                 \
			x = ((bsb_uint64_t)((b).ptr)[0]) << 56 | ((bsb_uint64_t)((b).ptr)[1]) << 48 | \
				((bsb_uint64_t)((b).ptr)[2]) << 40 | ((bsb_uint64_t)((b).ptr)[3]) << 32 | \
				((bsb_uint64_t)((b).ptr)[4]) << 24 | ((bsb_uint64_t)((b).ptr)[5]) << 16 | \
				((bsb_uint64_t)((b).ptr)[6]) << 8 | ((bsb_uint64_t)((b).ptr)[7]);         \
			(b).ptr += 8;                                                                 \
		}                                                                                 \
		else                                                                              \
			BSB_SET_ERROR(b);                                                             \
	} while (0)
// 取size字节到x(buff)中
#define BSB_IMPORT_byte(b, x, size)    \
	do                                 \
	{                                  \
		if ((b).ptr + size <= (b).end) \
		{                              \
			memcpy(x, b.ptr, size);    \
			(b).ptr += size;           \
		}                              \
		else                           \
		{                              \
			BSB_SET_ERROR(b);          \
		}                              \
	} while (0)
// 前者基础上, 若buf越界,结尾赋值0
#define BSB_IMPORT_zbyte(b, x, size)   \
	do                                 \
	{                                  \
		if ((b).ptr + size <= (b).end) \
		{                              \
			memcpy(x, b.ptr, size);    \
			(x)[size] = 0;             \
			(b).ptr += size;           \
		}                              \
		else                           \
		{                              \
			BSB_SET_ERROR(b);          \
			(x)[0] = 0;                \
		}                              \
	} while (0)
/********************************************以小端字节序取字节*********************************************/
#define BSB_LIMPORT_u08(b, x) BSB_IMPORT_u08(b, x)

#define BSB_LIMPORT_u16(b, x)                                                     \
	do                                                                            \
	{                                                                             \
		if ((b).ptr + 2 <= (b).end)                                               \
		{                                                                         \
			x = ((bsb_uint16_t)((b).ptr)[1]) << 8 | ((bsb_uint16_t)((b).ptr)[0]); \
			(b).ptr += 2;                                                         \
		}                                                                         \
		else                                                                      \
			BSB_SET_ERROR(b);                                                     \
	} while (0)

#define BSB_LIMPORT_u24(b, x)                                                            \
	do                                                                                   \
	{                                                                                    \
		if ((b).ptr + 3 <= (b).end)                                                      \
		{                                                                                \
			x = ((bsb_uint32_t)((b).ptr)[2]) << 16 | ((bsb_uint32_t)((b).ptr)[1]) << 8 | \
				((bsb_uint32_t)((b).ptr)[0]);                                            \
			(b).ptr += 3;                                                                \
		}                                                                                \
		else                                                                             \
			BSB_SET_ERROR(b);                                                            \
	} while (0)

#define BSB_LIMPORT_u32(b, x)                                                             \
	do                                                                                    \
	{                                                                                     \
		if ((b).ptr + 4 <= (b).end)                                                       \
		{                                                                                 \
			x = ((bsb_uint32_t)((b).ptr)[3]) << 24 | ((bsb_uint32_t)((b).ptr)[2]) << 16 | \
				((bsb_uint32_t)((b).ptr)[1]) << 8 | ((bsb_uint32_t)((b).ptr)[0]);         \
			(b).ptr += 4;                                                                 \
		}                                                                                 \
		else                                                                              \
			BSB_SET_ERROR(b);                                                             \
	} while (0)

#define BSB_LIMPORT_u64(b, x)                                                             \
	do                                                                                    \
	{                                                                                     \
		if ((b).ptr + 8 <= (b).end)                                                       \
		{                                                                                 \
			x = ((bsb_uint64_t)((b).ptr)[7]) << 56 | ((bsb_uint64_t)((b).ptr)[6]) << 48 | \
				((bsb_uint64_t)((b).ptr)[5]) << 40 | ((bsb_uint64_t)((b).ptr)[4]) << 32 | \
				((bsb_uint64_t)((b).ptr)[3]) << 24 | ((bsb_uint64_t)((b).ptr)[2]) << 16 | \
				((bsb_uint64_t)((b).ptr)[1]) << 8 | ((bsb_uint64_t)((b).ptr)[0]);         \
			(b).ptr += 8;                                                                 \
		}                                                                                 \
		else                                                                              \
			BSB_SET_ERROR(b);                                                             \
	} while (0)

/************************************************向bsb.buf中写入字节********************************************/
// 给定一个空buff,向buff中写,b.buf为写好的
#define BSB_EXPORT_u08(b, x)                   \
	do                                         \
	{                                          \
		if ((b).ptr && (b).ptr + 1 <= (b).end) \
		{                                      \
			*(((b).ptr)++) = (char)x;          \
		}                                      \
		else                                   \
			BSB_SET_ERROR(b);                  \
	} while (0)

#define BSB_EXPORT_u16(b, x)                    \
	do                                          \
	{                                           \
		if ((b).ptr && (b).ptr + 2 <= (b).end)  \
		{                                       \
			bsb_uint16_t t = (bsb_uint16_t)x;   \
			*(((b).ptr)++) = (t & 0xff00) >> 8; \
			*(((b).ptr)++) = (t & 0x00ff);      \
		}                                       \
		else                                    \
			BSB_SET_ERROR(b);                   \
	} while (0)

#define BSB_EXPORT_u24(b, x)                         \
	do                                               \
	{                                                \
		if ((b).ptr && (b).ptr + 3 <= (b).end)       \
		{                                            \
			bsb_uint32_t t = x;                      \
			*(((b).ptr)++) = (t & 0x00ff0000) >> 16; \
			*(((b).ptr)++) = (t & 0x0000ff00) >> 8;  \
			*(((b).ptr)++) = (t & 0x000000ff);       \
		}                                            \
		else                                         \
			BSB_SET_ERROR(b);                        \
	} while (0)

#define BSB_EXPORT_u32(b, x)                         \
	do                                               \
	{                                                \
		if ((b).ptr && (b).ptr + 4 <= (b).end)       \
		{                                            \
			bsb_uint32_t t = x;                      \
			*(((b).ptr)++) = (t & 0xff000000) >> 24; \
			*(((b).ptr)++) = (t & 0x00ff0000) >> 16; \
			*(((b).ptr)++) = (t & 0x0000ff00) >> 8;  \
			*(((b).ptr)++) = (t & 0x000000ff);       \
		}                                            \
		else                                         \
			BSB_SET_ERROR(b);                        \
	} while (0)

#define BSB_EXPORT_u40(b, x)                           \
	do                                                 \
	{                                                  \
		if ((b).ptr && (b).ptr + 5 <= (b).end)         \
		{                                              \
			bsb_uint64_t t = x;                        \
			*(((b).ptr)++) = (t & 0xff00000000) >> 32; \
			*(((b).ptr)++) = (t & 0x00ff000000) >> 24; \
			*(((b).ptr)++) = (t & 0x0000ff0000) >> 16; \
			*(((b).ptr)++) = (t & 0x000000ff00) >> 8;  \
			*(((b).ptr)++) = (t & 0x00000000ff);       \
		}                                              \
		else                                           \
			BSB_SET_ERROR(b);                          \
	} while (0)

#define BSB_EXPORT_u64(b, x)                                 \
	do                                                       \
	{                                                        \
		if ((b).ptr && (b).ptr + 8 <= (b).end)               \
		{                                                    \
			bsb_uint64_t t = x;                              \
			*(((b).ptr)++) = (t & 0xff00000000000000) >> 56; \
			*(((b).ptr)++) = (t & 0x00ff000000000000) >> 48; \
			*(((b).ptr)++) = (t & 0x0000ff0000000000) >> 40; \
			*(((b).ptr)++) = (t & 0x000000ff00000000) >> 32; \
			*(((b).ptr)++) = (t & 0x00000000ff000000) >> 24; \
			*(((b).ptr)++) = (t & 0x0000000000ff0000) >> 16; \
			*(((b).ptr)++) = (t & 0x000000000000ff00) >> 8;  \
			*(((b).ptr)++) = (t & 0x00000000000000ff);       \
		}                                                    \
		else                                                 \
			BSB_SET_ERROR(b);                                \
	} while (0)
// 从x中写入size字节到bsb.buf中
#define BSB_EXPORT_ptr(b, x, size)                           \
	do                                                       \
	{                                                        \
		if ((x || size == 0) && (b).ptr + size <= (b).end && \
			(b).ptr + size >= (b).buf)                       \
		{                                                    \
			memcpy((b).ptr, x, size);                        \
			(b).ptr += size;                                 \
		}                                                    \
		else                                                 \
			BSB_SET_ERROR(b);                                \
	} while (0)
// 前者基础上增加防止写越界
#define BSB_EXPORT_ptr_some(b, x, size)           \
	do                                            \
	{                                             \
		if ((b).ptr + size <= (b).end)            \
		{                                         \
			memcpy((b).ptr, x, size);             \
			(b).ptr += size;                      \
		}                                         \
		else if (((b).end != NULL))                \
		{                                         \
			memcpy((b).ptr, x, BSB_REMAINING(b)); \
			(b).ptr += BSB_REMAINING(b);          \
		}                                         \
	} while (0)
// 写字符串
// 例:printf("%d\n",sizeof "hello11");8   写入8-1字节
#define BSB_EXPORT_cstr(b, x)          \
	do                                 \
	{                                  \
		const int size = sizeof x - 1; \
		if ((b).ptr + size <= (b).end) \
		{                              \
			memcpy((b).ptr, x, size);  \
			(b).ptr += size;           \
		}                              \
		else                           \
			BSB_SET_ERROR(b);          \
	} while (0)

// 格式化写入字节  C9以上标准
// snprintf返回实际写入到字符串中的字符数(不包括空字符'\0')
#if defined(C9X)
#define BSB_EXPORT_sprintf(b, ...)                                                      \
	do                                                                                  \
	{                                                                                   \
		if ((b).end != 0)                                                               \
		{                                                                               \
			int l = snprintf((unsigned char *)(b).ptr, (b).end - (b).ptr, __VA_ARGS__); \
			if (l <= (b).end - (b).ptr)                                                 \
			{                                                                           \
				(b).ptr += l;                                                           \
			}                                                                           \
			else                                                                        \
			{                                                                           \
				BSB_SET_ERROR(b);                                                       \
			}                                                                           \
		}                                                                               \
	} while (0)
#else
// 格式化写字节
/*eg:
//BSB_EXPORT_sprintf(bsb, "hello%s,%d:%d:", "world",100,200);
//printf("%s\n", bsb.buf);
//helloworld,100:200:
*/
#define BSB_EXPORT_sprintf(b, args...)                                             \
	do                                                                             \
	{                                                                              \
		if ((b).end != 0)                                                          \
		{                                                                          \
			int l = snprintf((unsigned char *)(b).ptr, (b).end - (b).ptr, ##args); \
			if (l <= (b).end - (b).ptr)                                            \
			{                                                                      \
				(b).ptr += l;                                                      \
			}                                                                      \
			else                                                                   \
			{                                                                      \
				BSB_SET_ERROR(b);                                                  \
			}                                                                      \
		}                                                                          \
	} while (0)
#endif
// 写ipv4/ipv6地址
// 例:
//  struct in6_addr addr6;
//  inet_pton(AF_INET6, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", &addr6);
//  BSB_EXPORT_inet_ntop(bsb, AF_INET6, &addr6);
#define BSB_EXPORT_inet_ntop(b, f, s)                                                              \
	do                                                                                             \
	{                                                                                              \
		if ((b).end != 0)                                                                          \
		{                                                                                          \
			const unsigned char *r = inet_ntop(f, s, (unsigned char *)(b).ptr, (b).end - (b).ptr); \
			if (r)                                                                                 \
			{                                                                                      \
				(b).ptr += strlen(r);                                                              \
			}                                                                                      \
			else                                                                                   \
			{                                                                                      \
				BSB_SET_ERROR(b);                                                                  \
			}                                                                                      \
		}                                                                                          \
	} while (0)

/************************************以小端字节序写入***************************/
#define BSB_LEXPORT_u08(b, x) BSB_EXPORT_u08(b, x)

#define BSB_LEXPORT_u16(b, x)                   \
	do                                          \
	{                                           \
		if ((b).ptr + 2 <= (b).end)             \
		{                                       \
			bsb_uint16_t t = (bsb_uint16_t)x;   \
			*(((b).ptr)++) = (t & 0x00ff);      \
			*(((b).ptr)++) = (t & 0xff00) >> 8; \
		}                                       \
		else                                    \
			BSB_SET_ERROR(b);                   \
	} while (0)

#define BSB_LEXPORT_u32(b, x)                        \
	do                                               \
	{                                                \
		if ((b).ptr + 4 <= (b).end)                  \
		{                                            \
			bsb_uint32_t t = x;                      \
			*(((b).ptr)++) = (t & 0x000000ff);       \
			*(((b).ptr)++) = (t & 0x0000ff00) >> 8;  \
			*(((b).ptr)++) = (t & 0x00ff0000) >> 16; \
			*(((b).ptr)++) = (t & 0xff000000) >> 24; \
		}                                            \
		else                                         \
			BSB_SET_ERROR(b);                        \
	} while (0)
#define BSB_LEXPORT_u64(b, x)                                \
	do                                                       \
	{                                                        \
		if ((b).ptr + 8 <= (b).end)                          \
		{                                                    \
			bsb_uint64_t t = x;                              \
			*(((b).ptr)++) = (t & 0x00000000000000ff);       \
			*(((b).ptr)++) = (t & 0x000000000000ff00) >> 8;  \
			*(((b).ptr)++) = (t & 0x0000000000ff0000) >> 16; \
			*(((b).ptr)++) = (t & 0x00000000ff000000) >> 24; \
			*(((b).ptr)++) = (t & 0x000000ff00000000) >> 32; \
			*(((b).ptr)++) = (t & 0x0000ff0000000000) >> 40; \
			*(((b).ptr)++) = (t & 0x00ff000000000000) >> 56; \
			*(((b).ptr)++) = (t & 0xff00000000000000) >> 64; \
		}                                                    \
		else                                                 \
			BSB_SET_ERROR(b);                                \
	} while (0)
/***********************************************************************************************/
// b.ptr前进size字节
#define BSB_EXPORT_skip(b, size)                                    \
	do                                                              \
	{                                                               \
		if ((b).ptr + size <= (b).end && (b).ptr + size >= (b).buf) \
		{                                                           \
			(b).ptr += size;                                        \
			if ((b).ptr < (b).buf)                                  \
				(b).end = 0;                                        \
		}                                                           \
		else                                                        \
			BSB_SET_ERROR(b);                                       \
	} while (0)
// 后退size字节
#define BSB_EXPORT_rewind(b, size)                                  \
	do                                                              \
	{                                                               \
		if ((b).ptr - size <= (b).end && (b).ptr - size >= (b).buf) \
		{                                                           \
			(b).ptr -= size;                                        \
			if ((b).ptr < (b).buf)                                  \
				(b).end = 0;                                        \
		}                                                           \
		else                                                        \
		{                                                           \
			BSB_SET_ERROR(b);                                       \
		}                                                           \
	} while (0)
#define BSB_IMPORT_skip BSB_EXPORT_skip
#define BSB_LIMPORT_skip BSB_EXPORT_skip
#define BSB_IMPORT_rewind BSB_EXPORT_rewind
#define BSB_LIMPORT_rewind BSB_EXPORT_rewind
// 浮点型数据读写
#define BSB_IMPORT_double_or_float BSB_IMPORT_byte // 取
#define BSB_EXPORT_double_or_float BSB_EXPORT_ptr  // 写
/***********************************************************************************************/
// 指定的内存区域中查找指定字符的第一个匹配位置
// void *memchr(const void *s, int c, size_t n);
/*eg:

	BSB bsb1,bsb2;
	int pos1,pos2;
	 char buffer1[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
	 char buffer2[6] = "hello";
	BSB_INIT(bsb1, buffer1, sizeof(buffer1));
	BSB_INIT(bsb2, buffer2, sizeof(buffer2));
	 char ch1 = 0x33;
	 char ch2 = 'e';
	BSB_memchr(bsb1, ch1, pos1);
	BSB_memchr(bsb2, ch2, pos2);
	printf("position: %d %d\n", pos1,pos2);//2   1
*/
#define BSB_memchr(b, ch, pos)                                                   \
	do                                                                           \
	{                                                                            \
		if (((b).end == NULL))                                                     \
		{                                                                        \
			pos = 0;                                                             \
			break;                                                               \
		}                                                                        \
		unsigned char *s = memchr((unsigned char *)b.ptr, ch, BSB_REMAINING(b)); \
		if (s)                                                                   \
			pos = (unsigned char *)s - (unsigned char *)b.ptr;                   \
		else                                                                     \
			pos = 0;                                                             \
	} while (0)

// memcmp
// 如果两个内存区域内容相等,则返回0。
//  如果第一个不相等的字节在s1中的值小于s2中的值,则返回一个负值。
//  如果第一个不相等的字节在s1中的值大于s2中的值,则返回一个正值。
// 比较一个str和BSB结构体中的一段内存区域
#define BSB_memcmp(str, b, len) \
	((b).ptr + len <= (b).end ? memcmp(str, b.ptr, len) : -1)

// 查看b.ptr指针位置的值,如果当前指针位置不超过结尾位置,则返回当前指针位置的值,否则返回-1。
#define BSB_PEEK(b) ((b).ptr + 1 <= (b).end ? *b.ptr : -1)

#endif

ParseProtocol.c

包含一种接收协议帧方式

#include "ParseProtocol.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
// #include <asm/termbits.h>//自定义波特率头文件
// 需要将<asm/termbits.h>中的struct termios注释掉
#include <time.h>
#define BUFFER_SIZE 1024
// 自定义波特率设置,
//  int set_custom_baudrate(const char fd, int baudrate)
//  {

//     struct termios2 tio;
//     // 获取当前串口配置
//     if (ioctl(fd, TCGETS2, &tio) != 0)
//     {
//         perror("ioctl TCGETS2");
//         close(fd);
//         return -1;
//     }

//     // 设置自定义波特率
//     tio.c_cflag &= ~CBAUD;
//     tio.c_cflag |= BOTHER;   // 使用自定义波特率标志
//     tio.c_ispeed = baudrate; // 设置输入波特率
//     tio.c_ospeed = baudrate; // 设置输出波特率

//     // 应用新的串口配置
//     if (ioctl(fd, TCSETS2, &tio) != 0)
//     {
//         perror("ioctl TCSETS2");
//         close(fd);
//         return -1;
//     }

//     printf("set custom baudrate done! \n");

//     return 0;
// }

int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio, oldtio;
    if (tcgetattr(fd, &oldtio) != 0)
    {
        perror("SetupSerial 1");
        return -1;
    }

    bzero(&newtio, sizeof(newtio));
    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag = ~CSIZE;

    switch (nBits)
    {
    case 7:
        newtio.c_cflag |= CS7;
        break;
    case 8:
        newtio.c_cflag |= CS8;
        break;
    }

    switch (nEvent)
    {
    case 'O': // 奇校验
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        newtio.c_iflag |= (INPCK | ISTRIP);
        break;
    case 'E': // 偶校验
        newtio.c_iflag |= (INPCK | ISTRIP);
        newtio.c_cflag |= PARENB;
        newtio.c_cflag = ~PARODD;
        break;
    case 'N': // 无校验
        newtio.c_cflag = ~PARENB;
        break;
    }

    switch (nSpeed)
    {
    case 300:
        cfsetispeed(&newtio, B300);
        cfsetospeed(&newtio, B300);
        break;
    case 600:
        cfsetispeed(&newtio, B600);
        cfsetospeed(&newtio, B600);
        break;
    case 1200:
        cfsetispeed(&newtio, B1200);
        cfsetospeed(&newtio, B1200);
        break;
    case 2400:
        cfsetispeed(&newtio, B2400);
        cfsetospeed(&newtio, B2400);
        break;
    case 4800:
        cfsetispeed(&newtio, B4800);
        cfsetospeed(&newtio, B4800);
        break;
    case 9600:
        cfsetispeed(&newtio, B9600);
        cfsetospeed(&newtio, B9600);
        break;
    case 19200:
        cfsetispeed(&newtio, B19200);
        cfsetospeed(&newtio, B19200);
        break;
    case 38400:
        cfsetispeed(&newtio, B38400);
        cfsetospeed(&newtio, B38400);
        break;
    case 57600:
        cfsetispeed(&newtio, B57600);
        cfsetospeed(&newtio, B57600);
        break;
    case 115200:
        cfsetispeed(&newtio, B115200);
        cfsetospeed(&newtio, B115200);
        break;
    default:
        return -2;
        break;
    }
    if (nStop == 1)
    {
        newtio.c_cflag &= ~CSTOPB;
    }
    else if (nStop == 2)
    {
        newtio.c_cflag |= CSTOPB;
    }
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;
    tcflush(fd, TCIFLUSH);
    if ((tcsetattr(fd, TCSANOW, &newtio)) != 0)
    {
        perror("com set error");
        return -1;
    }
    printf("uart inint done!\n");
    return 1;
}
// 校验和
int check_sum(char *buf)
{
    unsigned short sum = 0;
    for (size_t i = CHECK_BEGIN; i <= CHECK_END; i++)
    {
        sum += buf[i];
    }
    if (*(unsigned short *)&buf[CHECK_SUM_BEGIN] == sum)
    {
        return 1;
    }
    // int sum = 0;
    // for (size_t i = CHECK_BEGIN; i <= CHECK_END; i++)
    // {
    // 	sum += buf[i];
    // }
    // printf("%d;%d\n",sum,buf[CHECK_SUM_BEGIN]);
    // if (buf[CHECK_SUM_BEGIN] == sum&0x000000ff)
    // {
    // 	return 1;
    // }

    else
    {
        return 0;
    }
}
// 初始化动态数组
void initArray(DynamicArray *a)
{

    a->buffer = (char *)malloc(INITIAL_CAPACITY * sizeof(char));

    if (a->buffer == NULL)
    {
        ERRORLOG("malloc error\n");
    }

    a->size = 0;
    a->capacity = INITIAL_CAPACITY;
}

// 释放动态数组
void freeArray(DynamicArray *a)
{
    free(a->buffer);
    a->buffer = NULL;
    a->size = 0;
    a->capacity = 0;
}

// 根据缓存数据大小动态扩容数组
// 案例:当串口阻塞时一次性接收数据大于缓存数据的缓冲区大小(>INITIAL_CAPACITY)若不动态扩容,则数据溢出
void ensureCapacity(DynamicArray *a, size_t additionalSize)
{
    size_t newCapacity = a->capacity;
    while (newCapacity < a->size + additionalSize)
    {
        newCapacity *= 2;
    }
    // 这里即使realloc内存小于原来内存,即使用realloc缩容,由于原来内存未释放,仍可以接着用
    char *newBuffer = (char *)realloc(a->buffer, newCapacity);
    if (newBuffer == NULL)
    {
        ERRORLOG("Memory realloc error\n");
    }
    a->buffer = newBuffer;
    a->capacity = newCapacity; // 接着使用原来内存大小或新扩容的内存大小
}

// 添加数据到动态数组
void addData(DynamicArray *a, const char *data, size_t dataSize)
{
    ensureCapacity(a, dataSize);
    memcpy(a->buffer + a->size, data, dataSize);
    // printf("a->size1:%ld,dataSize:%ld\n",a->size,dataSize);
    a->size += dataSize;
    // printf("a->size2:%ld\n",a->size);
}

// 从动态数组中移除一帧数据
void removeFrame(DynamicArray *a, size_t frameSize)
{
    if (frameSize > a->size)
    {
        ERRORLOG("remove frame size is larger than array size\n");
    }
    memmove(a->buffer, a->buffer + frameSize, a->size - frameSize);
    // printf("a->size:%ld\n",a->size);
    a->size -= frameSize;
    // printf("a->size -:%ld\n",a->size);
}

/*****************方式1解析代码****************************/
#if 1
int main()
{
    char *serial_device = "/dev/ttyUSB0";
    int baudrate = 115200;
    char *output_file_name = "test.txt";

    int serial_fd = open(serial_device, O_RDWR | O_NOCTTY | O_NDELAY);
    if (serial_fd == -1)
    {
        perror("Unable to open serial port");
        return 1;
    }

    int setret = 0;
    setret = set_opt(serial_fd, baudrate, 8, 'N', 1);

    if (setret == -1)
    {
        close(serial_fd);
        perror("set baudrate error\n");
    }

    // 打开输出文件
    FILE *output_file = fopen(output_file_name, "w");
    if (!output_file)
    {
        perror("Unable to open output file");
        close(serial_fd);
        return 1;
    }
    
    fd_set read_fds;
    DynamicArray array;

    initArray(&array);
    char readBuffer[BUFFER_SIZE] = {0}; // 用于每次存储读取的数据
    int fre=0;//帧计数,测试
    int total=0;//接收总字节数,测试
    while (1)
    {
        FD_ZERO(&read_fds);
        FD_SET(serial_fd, &read_fds);

        // 使用 select 等待数据
        int activity = select(serial_fd + 1, &read_fds, NULL, NULL, NULL);
        if (activity < 0)
        {
            perror("select error");
            break;
        }
        if (FD_ISSET(serial_fd, &read_fds))
        {
            int bytes_read = read(serial_fd, readBuffer, sizeof(readBuffer));

            if (bytes_read > 0)
            {
                total+=bytes_read;
                addData(&array, readBuffer, bytes_read);
                memset(readBuffer,0,sizeof(readBuffer));
            }
        }
        
        while (array.size >= FRAME_SIZE)
        {
            // 检查数组开头是否为帧头
            //if (*(unsigned short *)array.buffer==FRAME_HEADER&&check_sum(array.buffer))
            if (*(unsigned short *)array.buffer==FRAME_HEADER)
            {
                //测试
                // BSB bsb;
                // BSB_INIT(bsb,array.buffer,FRAME_HEADER);
                // BSB_EXPORT_skip(bsb,7);
                // unsigned int time=0;
                // BSB_LIMPORT_u32(bsb,time);
                //fprintf(output_file,"%u\n",time);
                
                /*这里找到一帧完整的数据,进行解析*/

                // for (size_t i = 0; i < 7; i++)
                // {
                //     printf("%02X ", array.buffer[i]);
                // }
                // printf("\n");

                fre++;

                // 移除这一帧数据
                removeFrame(&array, FRAME_SIZE);
            }
            else
            {
                // 不是帧头,移除第一个字节(继续从下一个字节开始判断)
                removeFrame(&array, 1);
            }
        }

        //printf("array.size: %ld,fre: %d,total: %d\n",array.size,fre,total);

    }
    //fclose(output_file);
    close(serial_fd);
    freeArray(&array);
    return 0;
}
#endif
/*****************方式二解析代码****************************/
#if 1
// 帧字段
typedef struct
{
    unsigned short head;
    unsigned short type;

    unsigned char Fre_len;
    unsigned int Cnt;
    unsigned short GPS_week;
    double GPS_Seconds;
    double Imu_lon;
    double Imu_lat;
    float Imu_h;
    float Att_h;
    float Att_p;
    float Att_r;
    float Vel_e;
    float Vel_n;
    float Vel_u;
    float Meter;
    float Deviation;
    float BiasX;
    float BiasY;

    unsigned short check_sum;
    unsigned short tail;

} Fre;
int main()
{
    char *serial_device = "/dev/ttyUSB0";
    int baudrate = 115200;
    char *output_file_name = "test.txt";

    int serial_fd = open(serial_device, O_RDWR | O_NOCTTY | O_NDELAY);
    if (serial_fd == -1)
    {
        perror("Unable to open serial port");
        return 1;
    }

    int setret = 0;
    setret = set_opt(serial_fd, baudrate, 8, 'N', 1);

    if (setret == -1)
    {
        close(serial_fd);
        perror("set baudrate error\n");
    }

    // 打开输出文件
    FILE *output_file = fopen(output_file_name, "w");
    if (!output_file)
    {
        perror("Unable to open output file");
        close(serial_fd);
        return 1;
    }

    fd_set read_fds;
    char data_buf[1024] = {0};
    int logcount = 0;
    int writeflag = 0;
    BSB bsb;
    BSB_INIT(bsb, data_buf, sizeof(data_buf));

    char readBuffer[BUFFER_SIZE] = {0}; // 用于每次存储读取的数据

    while (1)
    {
        FD_ZERO(&read_fds);
        FD_SET(serial_fd, &read_fds);

        // 使用 select 等待数据
        int activity = select(serial_fd + 1, &read_fds, NULL, NULL, NULL);
        if (activity < 0)
        {
            perror("select error");
            break;
        }
        if (FD_ISSET(serial_fd, &read_fds))
        {
            int bytes_read = read(serial_fd, readBuffer, sizeof(readBuffer));

            if (bytes_read > 0)
            {
                // 缓存收到的数据,缓存结束清除缓冲区
                BSB_EXPORT_ptr_some(bsb, readBuffer, bytes_read);
                memset(readBuffer, 0, sizeof(readBuffer));
                if (BSB_LENGTH(bsb) >= 2 * FRAME_SIZE) // 至少有一帧数据
                {
                    int bsb_in_len = BSB_LENGTH(bsb);
                    int i = 0;
                    //  找到收到buff中的第一帧数据
                    for (i = 0; i < bsb_in_len; i++)
                    {
                        if ((unsigned short)(bsb.buf[i + 1] << 8 | bsb.buf[i]) == (unsigned short)FRAME_HEADER)
                        // if (bsb.buf[i + 1] == 0xAD && bsb.buf[i] == 0x7E)
                        {
                            memmove(data_buf, &data_buf[i], bsb_in_len - i);
                            BSB_EXPORT_rewind(bsb, i);
                            break;
                        }
                    }
                    // 获取长度
                    int bas_in_len_for = BSB_LENGTH(bsb);
                    int fre_count = 0; // 记录解析完整帧的字节数。
                    char *p = bsb.buf;
                    // 解析缓存的数据 每次解析一整帧,不够一帧不解析
                    for (bas_in_len_for; bas_in_len_for >= FRAME_SIZE; bas_in_len_for -= FRAME_SIZE)
                    {
                        // 一帧一帧校验,即一帧一帧解析
                        // if (*((unsigned short *)p) == FRAME_HEADER && check_sum(p))
                        if (check_sum(p))
                        {
                            // 打印一帧
                            for (size_t i = 0; i < FRAME_SIZE; i++)
                            {
                                printf("%02X ", (unsigned char)p[i]);
                            }
                            printf("\n");

                            p += FRAME_SIZE;
                        }

                        fre_count += FRAME_SIZE;
                    }
                    // 循环退出时缓存的剩余不到一帧数据,缓存该半帧数据
                    if ((BSB_LENGTH(bsb) - fre_count) != 0)
                    {
                        int haf_ofset = 0;
                        haf_ofset = (BSB_LENGTH(bsb) - fre_count);
                        memmove(data_buf, &bsb.buf[fre_count], haf_ofset);
                    }
                    BSB_EXPORT_rewind(bsb, fre_count);
                }
            }
        }

        // printf("array.size: %ld,fre: %d,total: %d\n",array.size,fre,total);
    }
    fclose(output_file);
    close(serial_fd);
    return 0;
}
#endif

发送协议帧

#define SEND_FRE_LEN 32
#define SEND_DATA_LEN 26
char send_buf[32] = {0};
void send_fre(unsigned int *cut, double Imu_lon, double Imu_lat, float Imu_h, unsigned char vFlag, unsigned char errSta)
{

	BSB bsb;
	BSB_INIT(bsb, send_buf, SEND_FRE_LEN);

	BSB_EXPORT_u16(bsb, 0x5A54);
	BSB_EXPORT_u16(bsb, 0x3C3A);
	BSB_EXPORT_u08(bsb, SEND_DATA_LEN);
	// 加到一定值重新累加
	if (*cut == 65535)
	{
		*cut = 0;
	}
	BSB_EXPORT_u32(bsb, *cut);
	// 经纬高
	//  BSB_EXPORT_u64(bsb,Imu_lon);
	//  BSB_EXPORT_u64(bsb,Imu_lat);
	//  BSB_EXPORT_u32(bsb,Imu_h);
	BSB_EXPORT_ptr(bsb, &Imu_lon, 8);
	BSB_EXPORT_ptr(bsb, &Imu_lat, 8);
	BSB_EXPORT_ptr(bsb, &Imu_h, 8);
	// 有效标志
	BSB_EXPORT_u08(bsb, vFlag);
	// 定位误差
	BSB_EXPORT_u08(bsb, errSta);

	// 校验和
	unsigned short sum = 0;
	for (int i = 0; i < SEND_DATA_LEN; i++)
	{
		sum += send_buf[i];
	}
	BSB_EXPORT_u16(bsb, sum);

	// 帧尾
	BSB_EXPORT_u16(bsb, 0x5AFE);
	memset(send_buf, 0, sizeof(send_buf));
	*cut++;
}

注意:对于浮点型

    
    double ddd=(int)aaa;//ddd不等于-13.14555  
    int bbb=aaa;        //bbb不等于-13.14555

前面BSB中由于下面操作会影响浮点型数据解析和存储,所以对于浮点型存取不适用u32、u64的宏

最无脑方式:

//对于浮点型:
// float a=13.14f;
// BSB_IMPORT_double_or_float(bsb,&a,sizeof(a));//存
// BSB_IMPORT_double_or_float(bsb,&a,sizeof(a));//取

//已知通信双方大小端一样时,无论什么类型数据,存取直接无脑BSB_IMPORT_byte、BSB_EXPORT_ptr
// BSB bsb;
// BSB_INIT(bsb, send_buf, FRAME_SIZE);
// BSB_EXPORT_ptr(bsb, &fre.head, sizeof(fre.head));               // 2 bytes for unsigned short
// BSB_EXPORT_ptr(bsb, &fre.Fre_len, sizeof(fre.Fre_len));         // 1 byte for unsigned char
// BSB_EXPORT_ptr(bsb, &fre.Cnt, sizeof(fre.Cnt));                 // 4 bytes for unsigned int
// BSB_EXPORT_ptr(bsb, &fre.GPS_week, sizeof(fre.GPS_week));       // 2 bytes for unsigned short
// BSB_EXPORT_ptr(bsb, &fre.GPS_Seconds, sizeof(fre.GPS_Seconds)); // 8 bytes for double
// BSB_EXPORT_ptr(bsb, &fre.Imu_lon, sizeof(fre.Imu_lon));         // 8 bytes for double
// BSB_EXPORT_ptr(bsb, &fre.Imu_lat, sizeof(fre.Imu_lat));         // 8 bytes for double
// BSB_EXPORT_ptr(bsb, &fre.Imu_h, sizeof(fre.Imu_h));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Att_h, sizeof(fre.Att_h));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Att_p, sizeof(fre.Att_p));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Att_r, sizeof(fre.Att_r));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Vel_e, sizeof(fre.Vel_e));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Vel_n, sizeof(fre.Vel_n));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Vel_u, sizeof(fre.Vel_u));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Meter, sizeof(fre.Meter));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.Deviation, sizeof(fre.Deviation));     // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.BiasX, sizeof(fre.BiasX));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.BiasY, sizeof(fre.BiasY));             // 4 bytes for float
// BSB_EXPORT_ptr(bsb, &fre.check_sum, sizeof(fre.check_sum));     // 2 bytes for unsigned short

// BSB bsb;
// BSB_INIT(bsb, array.buffer, FRAME_SIZE);
// BSB_IMPORT_byte(bsb, &fre->head, sizeof(fre->head));		  // 2 bytes for unsigned short
// BSB_IMPORT_byte(bsb, &fre->Fre_len, sizeof(fre->Fre_len)); // 1 byte for unsigned char
// BSB_IMPORT_byte(bsb, &fre->Cnt, sizeof(fre->Cnt));				  // 4 bytes for unsigned int
// BSB_IMPORT_byte(bsb, &fre->GPS_week, sizeof(fre->GPS_week));		  // 2 bytes for unsigned short
// BSB_IMPORT_byte(bsb, &fre->GPS_Seconds, sizeof(fre->GPS_Seconds)); // 8 bytes for double
// BSB_IMPORT_byte(bsb, &fre->Imu_lon, sizeof(fre->Imu_lon)); // 8 bytes for double
// BSB_IMPORT_byte(bsb, &fre->Imu_lat, sizeof(fre->Imu_lat)); // 8 bytes for double
// BSB_IMPORT_byte(bsb, &fre->Imu_h, sizeof(fre->Imu_h));	  // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Att_h, sizeof(fre->Att_h)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Att_p, sizeof(fre->Att_p)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Att_r, sizeof(fre->Att_r)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Vel_e, sizeof(fre->Vel_e)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Vel_n, sizeof(fre->Vel_n)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Vel_u, sizeof(fre->Vel_u)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Meter, sizeof(fre->Meter));		  // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->Deviation, sizeof(fre->Deviation)); // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->BiasX, sizeof(fre->BiasX));		  // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->BiasY, sizeof(fre->BiasY));		  // 4 bytes for float
// BSB_IMPORT_byte(bsb, &fre->check_sum, sizeof(fre->check_sum)); // 2 bytes for unsigned short

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值