# uart_statemachine_ringbuffer_linux **Repository Path**: liudegui/uart_statemachine_ringbuffer_linux ## Basic Information - **Project Name**: uart_statemachine_ringbuffer_linux - **Description**: 本项目演示了两种 MCU 串口协议解析方案的实现: 方案一:缓冲区滑窗扫描 (RingBuffer) 方案二:层次状态机 (HSM) 使用 POSIX 线程在 Linux 环境下模拟 MCU 的 UART 中断机制 - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-04 - **Last Updated**: 2026-01-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # UART 协议解析 Demo ## 简介 本项目演示了两种 MCU 串口协议解析方案的实现: 1. **方案一:缓冲区滑窗扫描 (RingBuffer)** 2. **方案二:层次状态机 (HSM)** 使用 POSIX 线程在 Linux 环境下模拟 MCU 的 UART 中断机制。 ## 项目结构 ``` uart_statemachine_ringbuffer_linux/ ├── CMakeLists.txt ├── README.md ├── main.c ├── common/ # 公共定义 │ ├── types.h # 基础类型定义 │ └── uart_protocol.h # 协议定义 ├── hal/ # 硬件抽象层 │ ├── uart_hal.h # UART HAL 接口 │ └── uart_hal.c # UART HAL 实现(模拟中断) ├── ringbuffer_method/ # 方案一:缓冲区滑窗 │ ├── ringbuffer_parser.h # 解析器接口 │ └── ringbuffer_parser.c # 解析器实现 ├── hsm_method/ # 方案二:层次状态机 │ ├── state_machine.h # 状态机框架 │ ├── state_machine.c # 状态机实现 │ ├── hsm_parser.h # 解析器接口 │ └── hsm_parser.c # 解析器实现 └── business/ # 业务处理层 ├── cmd_handler.h # 命令处理接口 └── cmd_handler.c # 命令处理实现 ``` ## 协议格式 ### 简单帧格式 ``` | 帧头 | 长度(2B) | 命令类 | 命令 | 数据[LEN-2] | CRC16(2B) | 帧尾 | | 0xAA | LE | 1B | 1B | N bytes | LE | 0x55 | ``` - **帧头**: 固定 0xAA - **长度**: 2 字节小端序,表示 `命令类 + 命令 + 数据` 的总长度 - **命令类**: 命令分类 (SYS=0x01, SPI=0x02, OTA=0x04 等) - **命令**: 具体命令 - **数据**: 命令参数 - **CRC16**: 对 payload 部分的 CRC16-CCITT 校验 - **帧尾**: 固定 0x55 ### 命令类定义 | 命令类 | 值 | 说明 | |--------|--------|------------| | SYS | 0x01 | 系统命令 | | SPI | 0x02 | SPI Flash | | DIAG | 0x03 | 诊断命令 | | OTA | 0x04 | OTA 升级 | | CONFIG | 0x10 | 配置命令 | ## 两种方案对比 ### 方案一:缓冲区滑窗扫描 **原理:** - ISR 将接收的数据写入环形缓冲区 - 主循环周期性扫描缓冲区 - 通过滑动窗口查找帧头、校验帧尾和 CRC **优点:** - 实现简单直观 - CPU 占用低(主循环批量处理) - 适合固定格式协议 **缺点:** - 多次扫描开销 - 状态隐含在代码逻辑中 - 扩展复杂协议较困难 **适用场景:** - 简单定长协议 - 对实时性要求不高的场景 ### 方案二:层次状态机 (HSM) **原理:** - 每个字节到达触发一个事件 - 状态机根据当前状态处理事件 - 状态转换驱动协议解析 ```mermaid stateDiagram-v2 [*] --> IDLE IDLE --> LEN_LO : 0xAA LEN_LO --> LEN_HI : byte LEN_HI --> PAYLOAD : byte PAYLOAD --> CRC_LO : 收满 CRC_LO --> CRC_HI : byte CRC_HI --> TAIL : byte TAIL --> IDLE : 0x55 TAIL --> IDLE : 错误 PAYLOAD --> IDLE : 超时 ``` **优点:** - 结构清晰,易于维护 - 支持复杂多层协议 - 自恢复能力强 - 便于扩展和测试 **缺点:** - 实现复杂度较高 - 内存占用稍多 **适用场景:** - 复杂多层协议栈 - 需要高可靠性的系统 ## 架构设计 ### 分层设计 ``` ----------------------------- 业务层 命令处理、OTA 升级、Flash 操作 ----------------------------- 协议层 协议解析、帧组装、CRC 校验 ----------------------------- 驱动层 UART 中断处理、FIFO 管理 ----------------------------- ``` ### 中断模拟 使用 POSIX 线程模拟 MCU 的 UART 中断: ```c // 模拟 ISR 回调 static void uart_isr_callback(uint8_t port, uint32_t int_status) { uint8_t byte; // 从 FIFO 读取数据 while (uart_hal_rx_available(port)) { uart_hal_try_get_byte(port, &byte); // 写入解析器 rb_parser_put_byte(&parser, byte); } } ``` ## 编译运行 ### 编译 ```bash mkdir build && cd build cmake .. make ``` ### 运行 ```bash # 使用 RingBuffer 解析器 (默认) ./uart_parser_demo -r # 使用 HSM 解析器 ./uart_parser_demo -h # 运行两种解析器对比测试 ./uart_parser_demo -a # 查看帮助 ./uart_parser_demo --help ``` ## 业务命令支持 ### 系统命令 (SYS) | 命令 | 值 | 说明 | |---------------|--------|----------------| | GET_INFO | 0x81 | 获取设备信息 | | RST_NORMAL | 0x41 | 复位到正常模式 | | RST_BOOT | 0x47 | 复位到 Bootloader | | SET_BAUD | 0x44 | 设置波特率 | ### SPI Flash 命令 | 命令 | 值 | 说明 | |---------------|--------|----------------| | READ_ID | 0x81 | 读取 Flash ID | | READ | 0x82 | 读取数据 | | WRITE | 0xC1 | 写入数据 | | ERASE | 0x44 | 擦除扇区 | | GET_CRC | 0x84 | 获取 CRC | ### OTA 升级命令 | 命令 | 值 | 说明 | |---------------|--------|----------------| | START | 0x01 | 开始升级 | | DATA | 0x02 | 传输数据 | | END | 0x03 | 结束传输 | | VERIFY | 0x04 | 校验固件 |