1. 项目概述
跳转到“1. 项目概述”1.1 项目基本信息
跳转到“1.1 项目基本信息”- 项目名称: 老虎机控制系统 (TigerControl)
- 硬件平台: STM32F103RET6 微控制器
- 操作系统: FreeRTOS V10.x
- 通信协议: Modbus RTU (主站和从站)
- 主要功能: 工业动平衡机的伺服控制和IO管理
1.2 系统目标
跳转到“1.2 系统目标”- 替代传统PLC,实现高精度动平衡机控制
- 通过Modbus协议与上位机和伺服驱动器通信
- 提供安全的按钮控制和紧急停止功能
- 实现智能的工件夹紧控制
2. 系统架构分析
跳转到“2. 系统架构分析”2.1 整体架构图
跳转到“2.1 整体架构图”┌─────────────────────────────────────────────────────────────┐│ STM32F103RET6 主控制器 │├─────────────────┬───────────────┬───────────────────────────┤│ FreeRTOS 任务 │ 通信协议栈 │ 硬件抽象层 ││ │ │ ││ ┌─defaultTask │ ┌─Modbus主站 │ ┌─GPIO控制 ││ │ ┌─modbusTask │ │ ┌─Modbus从站 │ │ ┌─UART通信 ││ │ │ ┌─servoTask │ │ │ ┌─地址透传 │ │ │ ┌─定时器 ││ │ │ │ └─systemTask│ │ │ └─稀疏数组│ │ │ │ └─看门狗 ││ └─┴─┴─┴─────────┴─┴─┴─┴─────────┴─┴─┴─┴─────────────────────┤└─────────────────────────────────────────────────────────────┘ │ │ │ ┌───────▼───────┐ ┌───────▼───────┐ ┌───────▼───────┐ │ 上位机通信 │ │ 伺服驱动器 │ │ 现场IO设备 │ │ (Modbus从站) │ │ (Modbus主站) │ │ (按钮/阀门) │ └───────────────┘ └───────────────┘ └───────────────┘2.2 核心任务架构
跳转到“2.2 核心任务架构”FreeRTOS任务调度器├── defaultTask (优先级: Normal, 栈: 128*4) - 空闲任务├── modbusTask (优先级: Normal, 栈: 1200*4) - Modbus通信处理├── servoTask (优先级: High, 栈: 1200*4) - 伺服控制核心└── systemTask (优先级: Low, 栈: 512*4) - 系统监控和按钮控制3. 主要功能模块分析
跳转到“3. 主要功能模块分析”3.1 伺服控制模块 (tigerservo.c/h)
跳转到“3.1 伺服控制模块 (tigerservo.c/h)”3.1.1 功能概述
跳转到“3.1.1 功能概述”- 核心功能: 动平衡机伺服电机精确控制
- 通信方式: Modbus RTU主站模式
- 控制对象: 台达伺服驱动器(站号1和站号2)
- 控制精度: 支持32位参数控制
3.1.2 状态机设计
跳转到“3.1.2 状态机设计”伺服通信状态机流程:INIT → READ_INOUT_DATA → CHECK_INOUT_DIFF → WRITE_INOUT_DIFF ↓ ↑ CHECK_CTRL_DIFF ← READ_OUTPUT_DATA ↓ WRITE_CTRL_DIFF3.1.3 关键数据结构
跳转到“3.1.3 关键数据结构”typedef struct { ModbusConfig_t mb; // Modbus通信配置 ServoBalanceInput_t balanceInput; // 动平衡输入参数(21个) ServoBalanceOutput_t balanceOutput; // 动平衡输出参数(7个) ServoControllerState_t State; // 伺服控制器状态
// 通信状态管理 ServoCommState_t commState; // 状态机状态 uint8_t commIndex; // 通信索引 uint8_t retryCount; // 重试计数
// 数据缓存机制 uint32_t readInOutDataCache[21]; // 读取缓存 uint32_t writeInOutDataCache[21]; // 写入缓存 uint16_t readCtrlDataCache[2]; // 控制读取缓存 uint16_t writeCtrlDataCache[2]; // 控制写入缓存} A3ServoController_t;3.1.4 安全机制
跳转到“3.1.4 安全机制”- 智能重试策略: 上电初期频繁重试,后期降低频率
- 通信错误恢复: 超时和错误计数管理
- 数据一致性检查: 读写缓存差异检测
- 线程安全保护: 互斥锁保护关键操作
3.2 Modbus通信模块
跳转到“3.2 Modbus通信模块”3.2.1 双重角色设计
跳转到“3.2.1 双重角色设计”系统同时充当:
- Modbus主站: 与伺服驱动器通信
- Modbus从站: 接受上位机控制命令
3.2.2 地址透传机制
跳转到“3.2.2 地址透传机制”// 地址映射策略#define IS_STATION1_ADDR(addr) ((addr) >= 0x0600 && (addr) < 0x0700) // P6组参数#define IS_STATION2_DATA_ADDR(addr) ((addr) >= 0x5000 && (addr) < 0x6000) // 站2数据#define IS_STATION2_CTRL_ADDR(addr) ((addr) >= 0xA800 && (addr) < 0xA900) // 站2控制3.2.3 稀疏数组优化
跳转到“3.2.3 稀疏数组优化”typedef struct { uint16_t addr; // Modbus地址 uint16_t value; // 寄存器值} RegEntry_t;
typedef struct { RegEntry_t *entries; // 条目数组 uint16_t count; // 当前数量 uint16_t capacity; // 总容量} RegMap_t;3.2.4 数据有效性检查
跳转到“3.2.4 数据有效性检查”- 通信就绪检查: 防止在繁忙状态下写入
- 数据时效性检查: 超过5秒的数据被标记为过期
- 设备状态检查: 根据Modbus状态返回相应错误码
3.3 按钮控制模块 (button_control.c/h)
跳转到“3.3 按钮控制模块 (button_control.c/h)”3.3.1 按钮配置
跳转到“3.3.1 按钮配置”typedef enum { BUTTON_TYPE_EMERGENCY_STOP = 0, // 急停按钮 (PB8/IN0) BUTTON_TYPE_RESET, // 复位按钮 (PB9/IN1) BUTTON_TYPE_START, // 启动按钮 (PB10/IN2)} ButtonType_t;3.3.2 安全联锁逻辑
跳转到“3.3.2 安全联锁逻辑”启动按钮流程:检查系统就绪 → 检查急停状态 → 检查机器运行状态 → 检查气阀状态 ↓ ↓ ↓ ↓ 失败返回 失败返回 失败返回 智能处理气阀 ↓ 启动伺服电机3.3.3 状态管理
跳转到“3.3.3 状态管理”- 消抖算法: 10ms消抖时间,5ms扫描间隔
- 事件处理: 按下、释放、长按事件
- 状态同步: 与伺服控制器状态实时同步
3.4 气阀控制模块 (valveControl.c/h)
跳转到“3.4 气阀控制模块 (valveControl.c/h)”3.4.1 安全互锁机制
跳转到“3.4.1 安全互锁机制”bool Valve_IsSafeToOperate(void) { // 1. 急停状态检查 if(g_buttonControl.emergency_stop_active) return true; // 急停时允许开阀
// 2. 伺服运行状态检查 if(!g_servoController.State.bo_zeroSpeed) return false; // 伺服运行中禁止
// 3. 机器运行状态检查 if(g_buttonControl.machine_running) return false; // 机器运行中禁止
// 4. 伺服报警状态检查 if(g_servoController.State.bo_servoAlarmStatus) return false; // 报警时禁止
return true; // 所有检查通过}3.4.2 Modbus集成
跳转到“3.4.2 Modbus集成”- 命令处理: 处理上位机的开启/关闭命令
- 状态反馈: 实时更新气阀状态到Modbus寄存器
- 错误处理: 安全互锁错误时返回错误状态
4. 时序分析
跳转到“4. 时序分析”4.1 系统启动时序
跳转到“4.1 系统启动时序”时间轴: 0ms ────► 1000ms ────► 3000ms ────► 4000ms ────► │ │ │ │ HAL初始化 FreeRTOS启动 伺服初始化 正常运行状态 │ │ │ │ ├─GPIO初始化 ├─任务创建 ├─Modbus配置 ├─状态机循环 ├─UART初始化 ├─互斥锁创建 ├─参数写入 ├─数据同步 ├─定时器启动 └─调度器启动 └─连接建立 └─命令处理 └─外设配置4.2 任务调度时序
跳转到“4.2 任务调度时序”时间片调度 (10ms周期):servoTask ████████████████████████████████████████████modbusTask ░░░░████████░░░░████████░░░░████████░░░░████████systemTask ░░░░░░░░░░░░░░░░░░░░████░░░░░░░░░░░░░░░░░░░░████defaultTask ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0ms 10ms 20ms 30ms 40ms 50ms 60ms4.3 Modbus通信时序
跳转到“4.3 Modbus通信时序”主站通信周期 (约100ms):READ_INOUT → CHECK_DIFF → WRITE_DIFF → READ_OUTPUT → CHECK_CTRL → WRITE_CTRL ↑ ↓ └─────────────────────────── 循环 ────────────────────────────────────┘
从站响应 (<10ms):接收命令 → 地址验证 → 数据处理 → 响应发送5. 数据流分析
跳转到“5. 数据流分析”5.1 参数流向图
跳转到“5.1 参数流向图”上位机 ──Modbus从站──► MCU内存 ──状态机──► 伺服驱动器 ↑ ↓ ↓ └─ 状态反馈 ←──────── 数据缓存 ←──Modbus主站──┘ ↓ 按钮控制 → 安全逻辑 → 气阀控制5.2 关键数据结构
跳转到“5.2 关键数据结构”// 输入参数 (21个32位参数)struct BalanceInput { int32_t measureSpeed; // 测量转速 int32_t accelFactor; // 加速系数 int32_t decelFactor; // 减速系数 int32_t measureStopAngle; // 测量停止角度 // ... 其他17个参数};
// 输出参数 (7个32位参数)struct BalanceOutput { int32_t rotorSpeed; // 转子速度 int32_t feedbackPosition; // 回授位置 int32_t currentSlotNum; // 当前槽数 int32_t slipError; // 滑动误差 // ... 其他3个参数};6. 潜在问题分析
跳转到“6. 潜在问题分析”6.1 安全性问题
跳转到“6.1 安全性问题”6.1.1 缺乏输入验证
跳转到“6.1.1 缺乏输入验证”问题: 直接处理Modbus输入数据,缺乏范围检查
// 问题代码示例g_servoController.balanceInput.measureSpeed = (int32_t)value; // 未验证范围风险: 恶意输入可能导致设备异常 建议: 添加参数范围验证
// 改进建议if(value >= MIN_SPEED && value <= MAX_SPEED) { g_servoController.balanceInput.measureSpeed = (int32_t)value;} else { return MB_DATA_ERR; // 返回数据错误}6.1.2 急停处理不够完善
跳转到“6.1.2 急停处理不够完善”问题: 急停状态下仍允许某些操作 风险: 可能存在安全隐患 建议: 强化急停状态下的限制
6.1.3 线程同步问题
跳转到“6.1.3 线程同步问题”问题: 部分全局变量访问未完全保护
// 潜在竞态条件g_servoController.isDataDifferent = true; // 多线程访问建议: 使用原子操作或加强互斥锁保护
6.2 可靠性问题
跳转到“6.2 可靠性问题”6.2.1 内存管理
跳转到“6.2.1 内存管理”问题: 稀疏数组容量固定,可能溢出
if(map->count >= map->capacity) { return -1; /* 容量已满 */}建议: 动态扩容或更大的静态容量
6.2.2 错误恢复机制
跳转到“6.2.2 错误恢复机制”问题: 通信错误恢复较为简单 建议: 实现更智能的错误恢复策略
6.2.3 看门狗保护
跳转到“6.2.3 看门狗保护”问题: 看门狗喂狗逻辑可能不够健壮 建议: 增加任务健康检查
6.3 性能优化
跳转到“6.3 性能优化”6.3.1 任务调度优化
跳转到“6.3.1 任务调度优化”当前问题: 伺服任务10ms周期可能过于频繁 建议: 根据实际需求调整任务周期
6.3.2 通信优化
跳转到“6.3.2 通信优化”建议:
- 批量读写操作减少通信次数
- 实现通信缓存机制
- 优化CRC计算
7. 改进建议
跳转到“7. 改进建议”7.1 安全性改进
跳转到“7.1 安全性改进”- 参数验证框架: 建立统一的参数范围检查机制
- 安全状态机: 独立的安全监控状态机
- 故障注入测试: 增加故障模式测试
7.2 可维护性改进
跳转到“7.2 可维护性改进”- 配置参数化: 将硬编码常量移至配置文件
- 日志系统: 增加结构化日志记录
- 单元测试: 为关键模块添加单元测试
7.3 功能扩展
跳转到“7.3 功能扩展”- 远程诊断: 增加远程监控和诊断功能
- 数据记录: 历史数据记录和分析
- 多语言支持: 支持多种语言界面
8. 结论
跳转到“8. 结论”8.1 系统优势
跳转到“8.1 系统优势”- 架构清晰: 模块化设计,职责分离明确
- 实时性好: FreeRTOS保证实时响应
- 通信可靠: 双重Modbus角色设计巧妙
- 安全考虑: 多层安全互锁机制
8.2 主要风险
跳转到“8.2 主要风险”- 输入验证: 缺乏完善的输入数据验证
- 内存安全: 固定大小数组可能溢出
- 并发安全: 部分共享数据访问保护不足
8.3 总体评价
跳转到“8.3 总体评价”该项目展现了良好的嵌入式系统设计理念,但在安全性和健壮性方面还有改进空间。建议在投入生产使用前,重点加强输入验证、错误处理和安全机制。
来源:CSDN 原文,首次发布于 2025-09-11。