第77讲超长协议Spec分段输入技巧专栏地址嵌入式程序开发实战嵌入式双范式AI编程嵌入式开发必掌握嵌入式求职面试技术资料前言为什么超长协议Spec需要分段输入为什么重要工业级通信协议通常非常复杂帧结构复杂帧头、帧尾、地址、命令、数据、校验等多个字段命令众多Modbus有几十个功能码自定义协议可能有上百个命令数据结构复杂每种命令对应不同的数据结构定义繁多状态机复杂接收、解析、处理、响应等多个状态逻辑复杂完整的协议Spec可能包含数百行数据结构定义数十个函数接口定义复杂的状态机定义详细的错误处理规则如果一次性输入上下文溢出超出AI上下文窗口限制理解困难AI难以理解如此复杂的协议生成错误AI可能遗漏或混淆部分定义调试困难问题定位困难不知道哪里出错分段输入的作用将超长协议Spec分解为多个部分逐段输入AI逐步构建完整的协议实现。新手常见困惑困惑1“如何划分协议Spec的分段”困惑2“分段输入后如何保证整体一致性”困惑3“分段之间的依赖如何处理”困惑4“如何管理分段输入的进度”本文结构本文结构入门阶段进阶阶段高级阶段分段输入的必要性协议Spec分段策略基础分段模板数据结构分段函数接口分段状态机分段分段依赖管理分段集成验证分段进度跟踪第一部分入门阶段——建立整体认知1.1 分段输入的必要性超长协议Spec示例以Modbus协议为例完整Spec包含【Modbus协议完整Spec】 一、帧结构定义约50行 - RTU帧地址、功能码、数据、CRC - ASCII帧起始符、地址、功能码、数据、LRC、结束符 二、功能码定义约100行 - 01读线圈状态 - 02读离散输入 - 03读保持寄存器 - 04读输入寄存器 - 05写单个线圈 - 06写单个寄存器 - 15写多个线圈 - 16写多个寄存器 - ...共20功能码 三、数据结构定义约200行 - ModbusFrame_t帧结构 - ModbusReadCoilReq_t读线圈请求 - ModbusReadCoilRsp_t读线圈响应 - ...每种功能码对应请求和响应结构 四、函数接口定义约150行 - modbus_init()初始化 - modbus_process()处理帧 - modbus_read_coil()读线圈 - modbus_write_coil()写线圈 - ...每种功能码对应函数 五、状态机定义约100行 - 接收状态机 - 解析状态机 - 处理状态机 - 响应状态机 六、错误处理定义约100行 - 错误码定义 - 异常响应定义 - 错误处理函数 总计约700行Spec定义分段输入的优势分段输入优势上下文可控理解准确生成正确调试简单每段上下文独立不会溢出每段专注单一内容理解准确逐段生成逐步验证问题定位到分段1.2 协议Spec分段策略分段策略一按层次分段【按层次分段】 第一段基础定义层 - 帧结构定义 - 基础数据类型定义 - 宏定义 第二段功能码定义层 - 功能码枚举定义 - 功能码说明 第三段数据结构层 - 请求数据结构 - 响应数据结构 第四段函数接口层 - 公有函数接口 - 私有函数接口 第五段状态机层 - 状态定义 - 状态转换 - 状态处理 第六段错误处理层 - 错误码定义 - 错误处理函数分段策略二按功能分段【按功能分段】 第一段协议基础功能 - 帧组装 - 帧解析 - CRC计算 第二段读功能 - 读线圈 - 读离散输入 - 读保持寄存器 - 读输入寄存器 第三段写功能 - 写单个线圈 - 写单个寄存器 - 写多个线圈 - 写多个寄存器 第四段异常处理功能 - 异常响应 - 错误处理 - 超时处理分段策略三按复杂度分段【按复杂度分段】 第一段简单功能功能码01-04 - 读线圈状态 - 读离散输入 - 读保持寄存器 - 读输入寄存器 第二段中等功能功能码05-06 - 写单个线圈 - 写单个寄存器 第三段复杂功能功能码15-16 - 写多个线圈 - 写多个寄存器 第四段高级功能功能码22-23等 - 屏蔽写寄存器 - 读写多个寄存器1.3 基础分段模板模板一基础定义分段Prompt【协议Spec分段输入 - 第一段基础定义】 协议名称Modbus RTU 【帧结构定义】 一、RTU帧结构 - 地址域1字节从站地址1-247 - 功能码域1字节功能码1-127 - 数据域N字节根据功能码不同 - CRC域2字节CRC-16校验 二、帧格式 | 字段 | 字节数 | 说明 | |------|--------|------| | 地址 | 1 | 从站地址 | | 功能码 | 1 | 功能码 | | 数据 | N | 数据域 | | CRC | 2 | CRC-16 | 三、基础数据类型 - uint8_t字节类型 - uint16_t字类型 - uint32_t双字类型 四、宏定义 - MODBUS_ADDRESS_BROADCAST0广播地址 - MODBUS_ADDRESS_MIN1最小从站地址 - MODBUS_ADDRESS_MAX247最大从站地址 - MODBUS_FUNCTION_CODE_MIN1最小功能码 - MODBUS_FUNCTION_CODE_MAX127最大功能码 【输出要求】 生成基础定义头文件 - modbus_base.h包含帧结构定义、基础类型、宏定义模板二功能码分段Prompt【协议Spec分段输入 - 第二段功能码定义】 协议名称Modbus RTU 【功能码定义】 一、读功能码 - 0x01读线圈状态Read Coils - 0x02读离散输入Read Discrete Inputs - 0x03读保持寄存器Read Holding Registers - 0x04读输入寄存器Read Input Registers 二、写功能码 - 0x05写单个线圈Write Single Coil - 0x06写单个寄存器Write Single Register - 0x0F写多个线圈Write Multiple Coils - 0x10写多个寄存器Write Multiple Registers 三、其他功能码 - 0x17读写多个寄存器Read/Write Multiple Registers 四、异常功能码 - 0x80 功能码异常响应 【输出要求】 生成功能码定义头文件 - modbus_function_code.h包含功能码枚举定义、功能码说明第二部分进阶阶段——深入理解原理2.1 数据结构分段请求数据结构分段【数据结构分段 - 请求数据结构】 一、读线圈请求结构 c /** * brief 读线圈请求结构 */ typedef struct { uint8_t slave_address; /* 从站地址 */ uint8_t function_code; /* 功能码0x01 */ uint16_t start_address; /* 起始地址 */ uint16_t quantity; /* 数量1-2000 */ } ModbusReadCoilReq_t;二、读保持寄存器请求结构/** * brief 读保持寄存器请求结构 */typedefstruct{uint8_tslave_address;/* 从站地址 */uint8_tfunction_code;/* 功能码0x03 */uint16_tstart_address;/* 起始地址 */uint16_tquantity;/* 数量1-125 */}ModbusReadHoldingRegReq_t;三、写单个寄存器请求结构/** * brief 写单个寄存器请求结构 */typedefstruct{uint8_tslave_address;/* 从站地址 */uint8_tfunction_code;/* 功能码0x06 */uint16_tregister_address;/* 寄存器地址 */uint16_tregister_value;/* 寄存器值 */}ModbusWriteSingleRegReq_t;【输出要求】生成请求数据结构头文件modbus_request.h包含所有请求数据结构定义#### 响应数据结构分段【数据结构分段 - 响应数据结构】一、读线圈响应结构/** * brief 读线圈响应结构 */typedefstruct{uint8_tslave_address;/* 从站地址 */uint8_tfunction_code;/* 功能码0x01 */uint8_tbyte_count;/* 字节数 */uint8_tcoil_status[250];/* 线圈状态位打包 */}ModbusReadCoilRsp_t;二、读保持寄存器响应结构/** * brief 读保持寄存器响应结构 */typedefstruct{uint8_tslave_address;/* 从站地址 */uint8_tfunction_code;/* 功能码0x03 */uint8_tbyte_count;/* 字节数 */uint16_tregister_value[125];/* 寄存器值 */}ModbusReadHoldingRegRsp_t;三、写单个寄存器响应结构/** * brief 写单个寄存器响应结构 */typedefstruct{uint8_tslave_address;/* 从站地址 */uint8_tfunction_code;/* 功能码0x06 */uint16_tregister_address;/* 寄存器地址 */uint16_tregister_value;/* 寄存器值 */}ModbusWriteSingleRegRsp_t;【输出要求】生成响应数据结构头文件modbus_response.h包含所有响应数据结构定义### 2.2 函数接口分段 #### 公有函数接口分段【函数接口分段 - 公有函数】一、初始化函数/** * brief Modbus初始化 * param slave_address 从站地址1-247 * return 0成功-1参数错误 */int8_tmodbus_init(uint8_tslave_address);二、处理函数/** * brief Modbus帧处理 * param rx_data 接收数据 * param rx_len 接收长度 * param tx_data 发送数据输出 * param tx_len 发送长度输出 * return 0成功-1参数错误-2帧错误 */int8_tmodbus_process(uint8_t*rx_data,uint16_trx_len,uint8_t*tx_data,uint16_t*tx_len);三、读函数/** * brief 读线圈状态 * param req 请求结构 * param rsp 响应结构输出 * return 0成功-1参数错误 */int8_tmodbus_read_coil(ModbusReadCoilReq_t*req,ModbusReadCoilRsp_t*rsp);/** * brief 读保持寄存器 * param req 请求结构 * param rsp 响应结构输出 * return 0成功-1参数错误 */int8_tmodbus_read_holding_reg(ModbusReadHoldingRegReq_t*req,ModbusReadHoldingRegRsp_t*rsp);四、写函数/** * brief 写单个寄存器 * param req 请求结构 * param rsp 响应结构输出 * return 0成功-1参数错误 */int8_tmodbus_write_single_reg(ModbusWriteSingleRegReq_t*req,ModbusWriteSingleRegRsp_t*rsp);【输出要求】生成公有函数接口头文件modbus.h包含所有公有函数声明### 2.3 状态机分段 #### 接收状态机分段【状态机分段 - 接收状态机】一、状态定义/** * brief Modbus接收状态 */typedefenum{MODBUS_RX_STATE_IDLE0,/* 空闲状态 */MODBUS_RX_STATE_RECEIVING,/* 接收中 */MODBUS_RX_STATE_COMPLETE,/* 接收完成 */MODBUS_RX_STATE_ERROR/* 接收错误 */}ModbusRxState_t;二、状态转换是否错误IDLERECEIVING接收完成COMPLETEERROR三、状态处理/** * brief 接收状态机处理 * param byte 接收字节 * return 状态 */ModbusRxState_tmodbus_rx_state_machine(uint8_tbyte){staticModbusRxState_t stateMODBUS_RX_STATE_IDLE;staticuint16_trx_index0;staticuint32_tlast_time0;switch(state){caseMODBUS_RX_STATE_IDLE:/* 开始接收 */rx_index0;modbus_rx_buffer[rx_index]byte;stateMODBUS_RX_STATE_RECEIVING;last_timeget_tick();break;caseMODBUS_RX_STATE_RECEIVING:/* 检查帧间隔3.5字符时间 */if(get_tick()-last_timeMODBUS_FRAME_INTERVAL){/* 帧结束 */stateMODBUS_RX_STATE_COMPLETE;}else{/* 继续接收 */if(rx_indexMODBUS_MAX_FRAME_SIZE){modbus_rx_buffer[rx_index]byte;last_timeget_tick();}else{/* 缓冲区溢出 */stateMODBUS_RX_STATE_ERROR;}}break;caseMODBUS_RX_STATE_COMPLETE:caseMODBUS_RX_STATE_ERROR:/* 返回空闲状态 */stateMODBUS_RX_STATE_IDLE;break;}returnstate;}【输出要求】生成接收状态机源文件modbus_rx_state_machine.c包含接收状态机实现--- ## 第三部分高级阶段——掌握复杂应用 ### 3.1 分段依赖管理 #### 依赖关系图 mermaid flowchart TD A[基础定义] -- B[功能码定义] A -- C[数据结构] B -- C C -- D[函数接口] A -- E[状态机] C -- E D -- F[错误处理] E -- F依赖管理Prompt【分段依赖管理】 一、依赖关系 - 第二段功能码依赖第一段基础定义 - 第三段数据结构依赖第一段、第二段 - 第四段函数接口依赖第一段、第三段 - 第五段状态机依赖第一段、第三段 - 第六段错误处理依赖所有前段 二、输入顺序 1. 第一段基础定义无依赖 2. 第二段功能码定义依赖第一段 3. 第三段数据结构依赖第一段、第二段 4. 第四段函数接口依赖第一段、第三段 5. 第五段状态机依赖第一段、第三段 6. 第六段错误处理依赖所有前段 三、上下文加载 输入第N段时加载 - 第一段摘要基础定义 - 第N-1段完整内容上一段 - 第N段完整内容当前段 四、一致性检查 每段生成后检查 - 是否与前段定义一致 - 是否引用了未定义的内容 - 是否有命名冲突3.2 分段集成验证集成验证清单【分段集成验证清单】 一、编译验证 - [ ] 所有头文件是否编译通过 - [ ] 所有源文件是否编译通过 - [ ] 是否有未定义的引用 - [ ] 是否有重复定义 二、接口一致性验证 - [ ] 函数声明与定义是否一致 - [ ] 数据结构定义是否一致 - [ ] 宏定义是否一致 三、功能完整性验证 - [ ] 所有功能码是否实现 - [ ] 所有状态是否处理 - [ ] 所有错误是否处理 四、集成测试 - [ ] 单个功能测试 - [ ] 组合功能测试 - [ ] 异常情况测试3.3 分段进度跟踪进度跟踪表【分段进度跟踪】 协议名称Modbus RTU | 分段 | 内容 | 状态 | 完成时间 | |------|------|------|----------| | 1 | 基础定义 | 完成 | 2024-01-01 | | 2 | 功能码定义 | 完成 | 2024-01-01 | | 3 | 数据结构 | 完成 | 2024-01-02 | | 4 | 函数接口 | 进行中 | - | | 5 | 状态机 | 待开始 | - | | 6 | 错误处理 | 待开始 | - | 总进度50%3/6段完成 下一步完成第4段函数接口总结入门要点分段输入必要性解决上下文溢出、理解困难、生成错误问题分段策略按层次分段、按功能分段、按复杂度分段基础模板基础定义分段、功能码分段进阶要点数据结构分段请求数据结构、响应数据结构函数接口分段公有函数、私有函数状态机分段接收状态机、解析状态机、处理状态机高级要点依赖管理依赖关系图、输入顺序、上下文加载集成验证编译验证、接口一致性、功能完整性进度跟踪分段状态、总进度、下一步计划记住这些原则分段是手段分段输入是为了解决超长Spec问题依赖是关键分段间有依赖关系必须按顺序输入验证是保障每段生成后必须验证集成后必须集成验证跟踪是管理进度跟踪帮助管理分段输入进度下一讲预告第78讲将深入讲解模型选型策略探索用Vibe、量产用Spec学习如何根据开发阶段选择合适的AI模型和编程范式。