# simple_common_protocol **Repository Path**: liu-maolin6m0/simple_common_protocol ## Basic Information - **Project Name**: simple_common_protocol - **Description**: 一个应用层通信协议封装的库,专注于嵌入式设备串口、TCP/UDP自定义端对端的信息传输,可以做到摒弃动态内存分配,不使用任何C库支持。 - **Primary Language**: C - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-24 - **Last Updated**: 2026-03-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Simple Communication protocol (SCoP) ## 介绍 1. 一个简单通信协议的库,专注于嵌入式设备串口、TCP/UDP自定义端对端的信息传输,一个应用层的传输协议封装 2. 主要是为了省去嵌入式设备各种端口通信协议的设计,而设计的一个简单的、通用的通信协议库 3. 考虑到嵌入式设备的资源有限,动态内存申请的敏感性,本库有静态内存申请的版本,也有动态内存申请的版本 4. 考虑到单片机对于各类C库的支持,本库在静态内存版本中,可以完全不依赖任何C库 而动态内存申请版本中,如果没有自定义内存申请和释放函数,会默认使用C标准库的malloc()和free()函数,会引入 ## 软件架构 1. 本库的主要文件有: SCoP_types.h:包含了SCoP项目中使用的所有类型定义,枚举、结构体、宏定义等 SCoP_export.h:包含了SCoP项目中使用的所有函数声明 SCoP_conf.h:包含了SCoP项目中使用的所有宏定义,包括缓冲区长度、校验方式、是否使用动态内存申请等 pack_types.h:包含了SCoP项目中使用的所有包类型定义,以及包的操作函数指针结构体 pack_operations.c:包含了SCoP项目中使用的所有包操作函数的实现 buffer_types.h:缓冲区各个字段最大长度定义,以及对缓冲区的一些操作函数 buffer_operations.c:包含了SCoP项目中使用的所有缓冲区操作函数的实现 data_types.h:包含了SCoP项目中数据接收和发送相关的函数声明 data_operations.c:包含了SCoP项目中使用的所有数据操作函数的实现,包括数据接收和发送相关的函数实现 SCoP_export.c:包含了SCoP项目中使用的所有函数实现 data_check.c:包含了SCoP项目自带的校验方法,包括长度校验,和校验,crc16ModBus校验 2. 项目各个抽象层级 pack:协议包操作的抽象层级 buffer:缓冲区操作的抽象层级 data:数据接收和发送的抽象层级 数据的接收和发送 调用层级链路:SCoP实现-->data-->(buffer + pack) 各个参数的设置 调用层级链路:SCoP实现-->(buffer + pack) 或者 SCoP实现-->callback 3. 这样设计的主要目的: 将数据收发与缓冲区操作、协议包操作分离分层,实现解耦 SCoP的层级: SCoP实现层 数据操作层 (buffer + pack) ## 协议格式 1. 每个包格式: 起始段:最大2字节,最小1个字节 指令段:最大16字节,最小0个字节 校验段:最大32字节,最小0个字节 数据段:最大1024字节,可变长度 终止段:最大2字节,最小1个字节 ## 缓冲区申请的条件编译 1. 只申请一片发送缓冲区 半双工通信,而且接收发送都在一个函数中,此时接收时不能发送数据,发送时也不能接收数据,而且发送为分段发送 2. 申请一片发送缓冲区 + 发送数据临时缓冲区 半双工通信,而且接收发送都在一个函数中,此时接收时不能发送数据,发送时也不能接收数据,段合并为一个包发送 3. 申请一片接收缓冲区 + 申请额外的接收数据临时缓冲区 全双工通信,接收和发送可以在不同的缓冲区中,接收时可以发送数据,发送时也可以接收数据,发送为分段发送 4. 申请一片发送缓冲区 + 发送数据临时缓冲区 + 申请额外的发送数据临时缓冲区 全双工通信,接收和发送可以在不同的缓冲区中,接收时可以发送数据,发送时也可以接收数据,段合并为一个包发送 ## 移植到单片机中的方法 1. CMakeLists.txt去除,或者将USE_CONF_H_FILE置为true,CMakeLists.txt检测到USE_CONF_H_FILE为true则不会在编译添加任何宏定义 2. 在SCoP_conf.h文件中置USE_CONF_H_FILE为1,USE_SCOP_IN_MCU为1,USE_CODE_COMPILE_LIB为1,直接将源码添加到项目中即可 3. 倘若单片机能将源文件编译为库,也可以将SCoP项目编译为库,在项目中引用该库,在编译成库之后,只需要引入该库export文件夹下的头文件即可 SCoP_conf.h:包含了SCoP项目中使用的所有宏定义,包括缓冲区长度、校验方式、是否使用动态内存申请等 SCoP_types.h:包含了SCoP项目中使用的所有类型定义,枚举、结构体、宏定义等 SCoP_export.h:包含了SCoP项目中使用的所有函数声明 ## 配置SCoP项目的方法 1. 方法1:使用SCoP_conf.h文件配置项目,内部的conf_parse.h文件会根据配置定义相应的宏定义,在CMake环境中 编译项目时,需要将SCoP.conf文件的USE_CONF_H_FILE宏置为1 2. 方法2:使用CMakeLists.txt文件配置项目,会SCoP_parse.cmake文件会将SCoP.conf文件中的配置解析为CMake的宏定义 在编译时会为项目添加相应的宏定义,将SCoP.conf文件的USE_CONF_H_FILE宏置为0 3. 方法1一般用在嵌入式系统或者非Cmake构建的项目中,编译时直接将源码编译到项目中, 当然如果可以编译成库,也可以编译成库的方式添加到项目中 4. 方法2一般用在PC端Cmake构建的项目中,将SCoP项目作为一个库,在PC端项目中引用该库 ## 注意事项(重要) 1. 每个字段的最大长度在编译时就确定了,不能在运行时动态更改,在编译时更改各个段长度,切记:起始段、终止段最小需要1个字节,最长2字节。 CMake配置的项目可以在SCoP.conf中配置编译选项USE_MEMORY_SCHEME, 有三种方案:SMALL_MEMORY_SCHEME、MEDIUM_MEMORY_SCHEME、LARGE_MEMORY_SCHEME 使用SCoP_conf.h文件配置项目时,需要将USE_BUF_SCHEDULE宏定义为0,1,2, 分别对应SMALL_MEMORY_SCHEME、MEDIUM_MEMORY_SCHEME、LARGE_MEMORY_SCHEME SMALL_MEMORY_SCHEME各个段长度:起始段:1字节、指令段:8字节、校验段:8字节、数据段:256字节、终止段:1字节 MEDIUM_MEMORY_SCHEME各个段长度:起始段:2字节、指令段:16字节、校验段:16字节、数据段:512字节、终止段:2字节 LARGE_MEMORY_SCHEME各个段长度:起始段:2字节、指令段:16字节、校验段:32字节、数据段:1024字节、终止段:2字节 具体详细的定义可以查看源码的buffer_types.h文件 当然也可以根据项目的需求,在buffer_types.h文件中修改各个段最大长度的宏定义, 自定义各个段的长度,但是需要注意的是,起始段、终止段最小需要1个字节,最长2字节。 2. 虽然项目有转义字符的处理,但是在接收时如果遇到起始段的字符,但又没有真正开始接收数据,则会导致接收状态机进入错误状态, 为了防止接收时脏数据的情况,在开始接收前,先重置输入状态,即调用SCoP_ResetInput()函数 3. 运行时各个段的长度和检验方式不可随意更改,需要更改时应该接收和发送双方同时更改 4. SCoP库是非线程安全的,在多线程环境中使用时,需要注意线程安全问题 5. 在使用CMake构建项目时,如果想要生成示例程序,需要在CMakeLists.txt文件中将以下代码注释: ```cmake file(GLOB SRC_FILES SCoP_source/*.c SCoP_source/*.cpp ) add_library(${PROJECT_NAME} SHARED ${SRC_FILES}) ``` 将以下代码的注释取消: ```cmake file(GLOB SRC_FILES SCoP_source/*.c SCoP_source/*.cpp SCoP_test/*.c SCoP_test/*.cpp ) add_executable(${PROJECT_NAME} ${SRC_FILES}) ``` ## 库的用途 1. 实现自定义流式数据或者文件传输,例如:自定义协议的文件传输,自定义协议的流式数据传输等 不过只能以此库为基础,再封装一个流式文件传输的协议,此库的目标就是提供一个简单的通信协议,在未配置动态内存分配时, 不依赖于其他C库,旨在能在动态内存分配比较敏感和对C库的支持比较耗费资源的环境中使用,如某些单片机等