diff --git a/docs/modbus-active-report-analysis.md b/docs/modbus-active-report-analysis.md new file mode 100644 index 0000000..fc377a7 --- /dev/null +++ b/docs/modbus-active-report-analysis.md @@ -0,0 +1,248 @@ +# DLD154Pro Modbus 主动上报 — MCU 资源占用分析 + +> CH591R RISC-V @60MHz | 18KB RAM | BLE + 单路线圈 + RS485 + +--- + +## 1. 系统并发任务概览 + +``` +┌──────────────────────────────────────────────────────┐ +│ ISR 层 (抢占式, 不受主循环阻塞影响) │ +│ │ +│ TMR0 捕获 ISR ──── 线圈频率测量 (每周期触发) │ +│ TMR1 5ms ISR ──── 50ms tick / 继电器 / LED / PWM │ +│ UART0 RX ISR ──── RS485 接收缓冲 │ +│ BLE RF ISR ──── 蓝牙链路层 │ +│ │ +├──────────────────────────────────────────────────────┤ +│ 主循环 (round-robin, 被 rs485_send 阻塞时可暂停 45ms) │ +│ │ +│ TMOS_SystemProcess() ── BLE 协议栈调度 │ +│ poll_dbn_ble() ── BLE 数据收发 │ +│ cjq_srv() ── 线圈算法 / 进出车检测 │ +│ opt_input_poll() ── 光耦防抖 / 状态机 │ +│ modbus_poll() ── Modbus 帧处理 + 主动上报 TX │ +└──────────────────────────────────────────────────────┘ +``` + +**关键事实**: ISR 层永远不受 `rs485_send` 阻塞影响。线圈捕获/继电器输出/光耦消抖(TMR1 部分)在中断上下文运行,实时性有保证。 + +--- + +## 2. CPU 时间预算分析 + +### 2.1 中断负载 (固定开销,不可压缩) + +| 中断源 | 频率 | 单次耗时 | CPU 占比 | +|--------|------|---------|---------| +| TMR0 捕获 | ~60 kHz (50–120 kHz 线圈) | ~25 cycles | **~2.5%** | +| TMR1 5ms | 200 Hz | ~200 cycles (含 PWM 呼吸) | ~0.07% | +| UART0 RX | 主机轮询时偶发 | ~50 cycles | 可忽略 | +| BLE RF | 连接维护 ~30ms 间隔 | ~500 cycles | ~0.03% | +| **ISR 合计** | | | **~2.6%** | + +> TMR0 捕获 ISR 是最重的固定负载。线圈频率越高,中断越密。 + +### 2.2 主循环 (正常状态,无主动上报 TX) + +| 任务 | 单次耗时 | 说明 | +|------|---------|------| +| TMOS_SystemProcess | ~1.5 ms | BLE 协议栈 (底层在 ISR,这里是调度) | +| poll_dbn_ble | ~0.5 ms | 无待发数据时快速返回 | +| cjq_srv | ~1.0 ms | CAP_OK 触发时跑 vd1_task (IIR+基线+检测) | +| opt_input_poll | ~0.3 ms | 3 样本多数表决 + 状态机分支 | +| modbus_poll (RX only) | ~0.1 ms | 检查缓冲 + CRC 校验 | + +主循环一次约 **3.4 ms**。两次 CAP_OK 间隔 ~8.74ms,主循环约跑 2.5 次/测量窗,时间充裕。 + +### 2.3 主动上报 TX 阻塞时间 + +`rs485_send` 是逐字节忙等的: + +```c +for (i = 0; i < len; i++) { + while (R8_UART0_TFC != 0); // ← 等 TX FIFO 全空 (→ 等上一个字节发完) + R8_UART0_THR = data[i]; // 写 1 字节到 FIFO +} +``` + +UART0 TX FIFO 容量 8 字节,但代码**不等 FIFO 有空间就写满 8 字节**,而是每写 1 字节就等 FIFO 全空。这意味着每字节都经历完整的 1.04ms 传输等待。 + +| 帧类型 | 字节数 | 传输时间 @9600 | 传输时间 @19200 | 传输时间 @38400 | +|--------|--------|---------------|-----------------|-----------------| +| 全数据块上报 (FC 0x04) | 43B | **44.8 ms** | 22.4 ms | 11.2 ms | +| 异常响应 | 5B | 5.2 ms | 2.6 ms | 1.3 ms | +| 写回显 | 8B | 8.3 ms | 4.2 ms | 2.1 ms | + +### 2.4 主动上报各速率下的 CPU 占用 + +**150ms 活动间隔 (最坏情况)**: + +``` +每 150ms 窗口: + TX 阻塞 44.8 ms ← rs485_send(43B) + 主循环正常计算 ~50 ms ← 150 - 44.8 - 余量 + 可用于 BLE/算法 ~55 ms ← 剩余预算 + +主循环 CPU 占比: (44.8 + 50) / 150 = 63% +其中 TX 阻塞占比: 44.8 / 150 = 30% +``` + +**800ms 空闲间隔**: + +``` +TX 阻塞占比: 44.8 / 800 = 5.6% +主循环 CPU 占比: ~30% +``` + +**继电器翻转事件 (立即上报)**: + +``` +TX 阻塞 44.8ms,单次冲击。翻转频率低(最多每秒数次进出车),不构成持续负载。 +``` + +--- + +## 3. 关键风险点 + +### 3.1 ⚠️ 主循环阻塞 45ms 期间的影响 + +`rs485_send` 阻塞期间,以下主循环任务被暂停: + +| 任务 | 影响 | 严重程度 | +|------|------|---------| +| **cjq_srv** (线圈算法) | CAP_OK 积压 ~5 次 (45ms ÷ 8.74ms)。恢复后主循环逐次消化,算法不丢数据,但响应延迟 +45ms | 🟡 轻微 | +| **opt_input_poll** (光耦) | 防抖采样暂停 45ms。光耦输入若在此期间变高又变低,可能丢失 <45ms 的短脉冲 | 🟡 轻微 | +| **TMOS_SystemProcess** (BLE) | BLE 协议栈调度延迟 45ms。连接监控超时通常 ≥2s,**不受影响** | 🟢 安全 | +| **modbus_poll** (RX) | 主机若在 TX 期间发来命令,UART ISR 正常收进缓冲,TX 结束后才处理 → 响应延迟 +45ms | 🟡 轻微 | + +### 3.2 ✅ 不受影响的部分 + +| 机制 | 原因 | +|------|------| +| 继电器输出 | TMR1 ISR (5ms) 独立运行,不经过主循环 | +| 线圈频率测量 | TMR0 捕获 ISR 独立运行 | +| 光耦复位 (模式 6) | `opt_input_poll` 中的复位逻辑暂停 45ms,但 400ms 的复位门槛远大于阻塞时间 | +| UART 接收 | ISR 独立填充 `_rx_buf` | + +### 3.3 🟢 结论 + +**@9600 波特率,150ms 主动上报可行。** 30% TX 阻塞是临界值——主循环仍有 ~55ms/150ms 的余量处理线圈算法和 BLE。不会丢检测事件,不会断蓝牙,继电器输出不受影响。 + +--- + +## 4. RAM 占用 + +### 4.1 新增静态变量 (BSS) + +| 变量 | 大小 | 说明 | +|------|------|------| +| `_auto_rpt_enable` | 1B | 主动上报使能标志 | +| `_active_threshold` | 2B | 活动阈值 | +| `_rpt_last_ms` | 4B | 上次上报时刻 | +| `_rpt_active` / `_rpt_hyst_cnt` | 2B | 速率状态机 | +| `_last_relay_off_10ms` | 4B | 继电器释放时刻 | +| `_last_relay_on_10ms` | 4B | 继电器吸合时刻 | +| `_last_relay_state` | 1B | 继电器边沿检测 | +| `_misc_time_type` | 2B | 时间类型 | +| `_misc_time_value` | 4B | 时间值 10ms | +| `_relay_engage_cnt` | 4B | 继电器累计次数 | +| **合计** | **28B** | | + +### 4.2 栈峰值 + +| 调用链 | 栈占用 | +|--------|--------| +| `modbus_poll()` 局部变量 | ~20B | +| → `send_full_data()` 局部 buf[43] | 43B | +| → `build_full_data()` 局部 buf[38] + 临时变量 | ~60B | +| → `rs485_send()` 局部变量 | ~10B | +| → `crc16()` 局部变量 | ~4B | +| **调用链合计** | **~140B** | + +> 加中断嵌套预留 ~200B,栈峰值约 **350B**。CH591R 默认栈 2KB(可配置),余量充足。 + +### 4.3 总体 RAM + +| 项目 | 大小 | +|------|------| +| 新增 BSS | 28B | +| 栈峰值增量 | ~140B (Modbus 调用链) | +| CRC16 表 | 512B (const → Flash,不计 RAM) | +| **RAM 增量** | **~170B** | + +CH591R 共 18KB RAM(含 BLE 协议栈 + 应用),Modbus 模块新增 < 1%。 + +--- + +## 5. Flash 占用 + +| 文件 | 大小 | +|------|------| +| `rs485_modbus.c` | ~8.5 KB | +| `rs485_modbus.h` | ~2.2 KB | +| `rs485_700bs.c` 增量 (去 static) | ~0 | +| `peripheral_main.c` 增量 (分派) | ~20B | +| **合计** | **~8.5 KB** | + +CH591R Flash: 256KB (应用区 28KB 或 18KB,取决于 OTA 配置)。增量约占应用区 30%(28KB 配置)或 47%(18KB 配置)。**18KB OTA 配置下偏紧**。 + +--- + +## 6. 优化建议 + +### 6.1 提高波特率 (影响最大) + +| 波特率 | TX 阻塞 (43B) | 活动态 CPU 占比 | 改善 | +|--------|--------------|----------------|------| +| 9600 | 44.8 ms | 30% | 基线 | +| **19200** | **22.4 ms** | **15%** | **↓50%** | +| 38400 | 11.2 ms | 7.5% | ↓75% | +| 115200 | 3.7 ms | 2.5% | ↓92% | + +> **建议**: 开启主动上报时,波特率至少用 19200。CH591R UART0 支持到 6 Mbps,硬件无瓶颈。 + +### 6.2 优化 TX FIFO 利用率 (代码级) + +当前每字节等 FIFO 全空,改为填充 8 字节后再等: + +```c +void rs485_send_fast(const uint8_t *data, uint8_t len) { + RS485_RE_TX(); + mDelayuS(100); + uint8_t i = 0; + while (i < len) { + uint8_t space = 8 - R8_UART0_TFC; // FIFO 剩余空间 + uint8_t chunk = (len - i < space) ? (len - i) : space; + for (uint8_t j = 0; j < chunk; j++) + R8_UART0_THR = data[i + j]; + i += chunk; + if (i < len) + while (R8_UART0_TFC >= 8); // 等至少 1 字节空间 + } + while (R8_UART0_TFC != 0); + mDelayuS(500); + RS485_RE_RX(); +} +``` + +效果:不减少总 TX 时间(波特率决定),但减少忙等循环次数 43→6 次,降低指令开销。 + +### 6.3 活动上报间隔可调 + +当前硬编码 150ms/800ms。可考虑通过 HR 寄存器暴露间隔参数,让主机根据场景调优。 + +--- + +## 7. 总结 + +| 维度 | 评估 | 说明 | +|------|------|------| +| **实时性** | ✅ 安全 | ISR 层不受 TX 阻塞影响;主循环延迟 45ms 可接受 | +| **CPU** | 🟡 @9600 临界 | 活动态 30% TX 阻塞,主循环仍有 55ms 余量 | +| **CPU** | 🟢 @19200 充裕 | 活动态 15% TX 阻塞,余量充足 | +| **RAM** | 🟢 充裕 | 增量 < 170B, < 1% 总 RAM | +| **Flash** | 🟡 18KB OTA 配置偏紧 | 增量 ~8.5KB,占应用区 47% | +| **BLE** | 🟢 安全 | 45ms 远小于连接超时 (≥2s) | +| **线圈检测** | 🟢 安全 | TMR0/TMR1 ISR 独立,不丢边沿 |