【Protocol】一个简洁实用的自定义通信协议

简介: 【Protocol】一个简洁实用的自定义通信协议

Protocol

一个简洁实用的基于字节的自定义通信协议。

协议帧定义

/* Frame format definition */
typedef struct msg_frame
{
    uint32_t head;                   /* Frame header */
    uint8_t type;                    /* Device  ID */
    uint8_t cmd;                     /* Order code */
    uint16_t code;                   /* Function code */
    uint16_t datalen;                /* Data length */
    uint8_t data[MSG_FRAME_MAX_LEN]; /* Data storage area */
    uint16_t chkval;                 /* Check value */
    uint16_t tail;                   /* Frame end */
} msg_frame_t;

帧格式说明

说明 帧头 设备 ID 指令码 功能码 数据长度 数据存储区 校验值 帧尾
变量名 head type cmd code datalen data chkval tail
长度(Byte) 4 1 1 2 2 n 2 2

数据存储区最大长度,单位为字节

#define MSG_FRAME_MAX_LEN   64

可处理有效数据最大长度,单位为字节

#define MSG_BUF_MAX_LEN     96

帧头:有效数据的开始。

#define MSG_FRAME_HEAD0     0xED
#define MSG_FRAME_HEAD1     0xB9
#define MSG_FRAME_HEAD2     0x55
#define MSG_FRAME_HEAD3     0xAA

设备 ID:设备种类、地址或者设备类型

uint8_t type;

指令码:对设备的造作命令,如 open、close、read、write 等。

uint8_t cmd;

功能码:对指令码的进一步说明。

uint16_t code;

数据长度:数据存储区中数据的长度,单位为字节

uint16_t datalen;

数据存储区:用来存储要传输的数据。

uint8_t data[MSG_FRAME_MAX_LEN];

校验值:基于 CRC 校验(可自定义)。

static uint16_t mc_check_crc16(const uint8_t *data, uint8_t len)
{
    uint16_t crc16 = 0xffff;
    uint8_t state, i, j;
    for(i = 0; i < len; i++ )
    {
        crc16 ^= data[i];
        for( j = 0; j < 8; j++)
        {
            state = crc16 & 0x01;
            crc16 >>= 1;
            if(state)
            {
                crc16 ^= 0xa001;
            }
        }
    }
    return crc16;
}

帧尾:有效数据的结束。

#define MSG_FRAME_TAil0     0x5A
#define MSG_FRAME_TAil1     0xA5

API 说明

数据解包

/* Packet decoding */
msg_pkg_t *unpkg_frame(const uint8_t *_msg_buf, const uint8_t size)

数据打包

/* Packet packaging */
msg_buf_t *pkg_frame(const msg_frame_t *_msg_pkg)

测试验证

测试环境:Visual Studio 2022 IDE

测试代码:

void pkg_test_cmd(void)
{
    kprintf("\r\n----- Packing and unpacking test begin -----\r\n");

    msg_frame_t my_frame = { 0x01, 0x02, 0xabcd, 0x8,
            {0x12, 0x34, 0x56,0x78, 0xab, 0xcd, 0xef, 0x5a} };

    uint8_t my_buf[] = { 0xed, 0xb9, 0x55, 0xaa, 0x0a, 0x2c, 0x80, 0x00,
            0x00, 0x04, 0x12, 0x34, 0xab, 0xcd, 0xe5, 0x50, 0x5a, 0xa5 };

    msg_buf_t* msg_buf = pkg_frame(&my_frame);
    msg_buf_print("frame to buffer test", msg_buf);

    msg_pkg_t* msg_pkg = unpkg_frame(msg_buf->buf_ptr, msg_buf->buf_size);
    msg_pkg_print("buffer to frame test", msg_pkg);

    msg_pkg = unpkg_frame(my_buf, sizeof(my_buf) / sizeof(uint8_t));
    msg_pkg_print("buffer to frame test", msg_pkg);

    kprintf("\r\n---- Packing and unpacking test end ---- \r\n");
}

运行结果:

----- Packing and unpacking test begin -----

frame to buffer test
size   (DEC):  22
data   (HEX):  ed b9 55 aa 01 02 ab cd 00 08 12 34 56 78 ab cd ef 5a 47 14 5a a5
state  (DEC):  0

buffer to frame test
type   (HEX):  01
cmd    (HEX):  02
code   (HEX):  ab cd
datalen(DEC):  8
data:  (HEX):  12 34 56 78 ab cd ef 5a
state: (DEC):  0

buffer to frame test
type   (HEX):  0a
cmd    (HEX):  2c
code   (HEX):  80 00
datalen(DEC):  4
data:  (HEX):  12 34 ab cd
state: (DEC):  0

---- Packing and unpacking test end ----
请按任意键继续. . .


代码获取

  • Github 仓库
相关文章
|
6月前
|
Swift iOS开发
Swift 语言: 什么是协议(Protocol)?如何实现和使用协议?
Swift 语言: 什么是协议(Protocol)?如何实现和使用协议?
194 2
|
5月前
|
网络协议 IDE 开发工具
TCP通信协议及代码细节
TCP通信协议及代码细节
35 0
|
6月前
|
XML JSON API
⚡REST 和 SOAP 协议有什么区别?
这篇文章对比了 REST 和 SOAP 两种常见的 Web API 规范。REST 是一种 API 架构风格,遵循客户端-服务器、无状态和缓存等原则,使用 HTTP 协议和 JSON 格式,适合轻量级、高兼容性的场景。SOAP 是一种基于 XML 的网络服务访问协议,提供消息级安全性和 ACID 合规性,适用于企业级应用。REST 的优点包括前后端分离、浏览器兼容和带宽效率,而 SOAP 适用于需要高级安全特性的应用。除了 REST 和 SOAP,还有 gRPC 和 GraphQL 等其他选择。
嵌入式开发中自定义协议的解析与组包
嵌入式开发中自定义协议的解析与组包
|
存储 网络协议 Dubbo
如何设计可向后兼容的RPC协议
HTTP协议(本文HTTP默认1.X)跟RPC协议又有什么关系呢?都属于应用层协议。
129 0
|
测试技术 Python
07 WebSocket接口:如何测试一个完全陌生的协议接口?
07 WebSocket接口:如何测试一个完全陌生的协议接口?
|
监控 网络协议 安全
一文了解HTTP、HTTPS、TCP、UDP、Websocket(论点:概念、通信流程、异同点、应用领域)
一文了解HTTP、HTTPS、TCP、UDP、Websocket(论点:概念、通信流程、异同点、应用领域)
|
移动开发 网络协议 定位技术
Websocket协议的介绍和使用场景
Websocket协议的介绍和使用场景
222 0
|
存储 编译器 调度
Swift-进阶 13:协议Protocol
Swift-进阶 13:协议Protocol
328 0