docs: 活动上报+继电器翻转 最坏情况对线圈检测的影响分析
关键发现: - 两个 TX 不会背靠背: relay flip TX 在入口处 return, 活动 TX 在下方 必然间隔一次 cjq_srv (≥3ms) - @115200: 总干扰窗口 11.6ms, CAP_OK 最多积压 1 次, 检测延迟 +16% - @9600: 总干扰窗口 92ms, CAP_OK 积压 5 次, 检测延迟 +170% ← 不可接受 - loop1_CAP_OK 是 ISR 标志位, 不会因主循环阻塞丢失
This commit is contained in:
@@ -0,0 +1,142 @@
|
|||||||
|
# 最坏情况:活动上报 + 继电器翻转 对线圈检测的影响
|
||||||
|
|
||||||
|
> 场景:变化量持续活跃 (150ms 上报) + 车辆进出触发继电器翻转 (即时上报)
|
||||||
|
> 波特率:115200 (Modbus 默认)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 为什么两个 TX 不会背靠背?
|
||||||
|
|
||||||
|
`modbus_report_schedule()` 的结构:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void modbus_report_schedule(void)
|
||||||
|
{
|
||||||
|
// ① 先检查继电器翻转 (入口判断)
|
||||||
|
if (relay != _last_relay_state) {
|
||||||
|
send_full_data(); // 4.3ms TX
|
||||||
|
return; // ← 立即返回,不往下走
|
||||||
|
}
|
||||||
|
|
||||||
|
// ② 再检查活动/空闲定时器
|
||||||
|
if (is_active() && elapsed >= 150ms) {
|
||||||
|
send_full_data(); // 4.3ms TX
|
||||||
|
// ← 返回后,函数继续到末尾,退出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**两个 `send_full_data()` 不在同一次 `modbus_poll` 调用中**。继电器翻转的 TX 在入口处拦截后直接 `return`,不会同时走活动上报路径。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 最坏情况时序
|
||||||
|
|
||||||
|
假设 t=0 时活动定时器到期,同时 TMR1 ISR 在 TX 期间翻转了继电器:
|
||||||
|
|
||||||
|
```
|
||||||
|
t=0.0 Main_Circulation:
|
||||||
|
cjq_srv() ← 正常处理 CAP_OK
|
||||||
|
opt_input_poll()
|
||||||
|
modbus_poll()
|
||||||
|
→ modbus_report_schedule()
|
||||||
|
→ relay 未翻转, 活动定时器到期
|
||||||
|
→ send_full_data() ─────────── TX 阻塞 4.3ms ─┐
|
||||||
|
t=1.5 [TMR1 ISR] relay 翻转 (cjq_srv 上次已判定进车) │ ISR 不受阻
|
||||||
|
t=4.3 TX 结束 ──────────────────────────────────────────┘
|
||||||
|
→ _rpt_last_ms = now, 函数返回
|
||||||
|
|
||||||
|
t=7.5 下一次 Main_Circulation (间隔 ~3ms):
|
||||||
|
TMOS_SystemProcess()
|
||||||
|
poll_dbn_ble()
|
||||||
|
cjq_srv() ← 处理中间的 CAP_OK (最多积压 1 次)
|
||||||
|
opt_input_poll()
|
||||||
|
modbus_poll()
|
||||||
|
→ modbus_report_schedule()
|
||||||
|
→ relay != _last_relay_state ← 翻转被检测到
|
||||||
|
→ update_misc_time() ← 算车间距/通过时间
|
||||||
|
→ send_full_data() ─────────── TX 阻塞 4.3ms ─┐
|
||||||
|
t=11.8 TX 结束 ──────────────────────────────────────────┘
|
||||||
|
|
||||||
|
t=11.8+ 正常恢复
|
||||||
|
```
|
||||||
|
|
||||||
|
**关键**:t=4.3 到 t=7.5 之间有 ~3ms 的正常主循环,`cjq_srv` 在这个窗口内运行。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 对线圈检测的量化影响
|
||||||
|
|
||||||
|
| 参数 | 值 | 说明 |
|
||||||
|
|------|-----|------|
|
||||||
|
| 单次 TX 阻塞 | **4.3 ms** | 115200, 43 字节 |
|
||||||
|
| 两次 TX 间隔 | **≥3 ms** | 主循环其他任务 (cjq_srv + opt + BLE) |
|
||||||
|
| 总干扰窗口 | **~11.6 ms** | 含中间的 3ms 正常处理 |
|
||||||
|
| CAP_OK 周期 | **8.74 ms** | 测量窗长度 |
|
||||||
|
| 最多积压 CAP_OK | **1 次** | 11.6ms ÷ 8.74ms = 1.3 |
|
||||||
|
| cjq_srv 处理机会 | **窗口中间有 1 次** | 两次 TX 之间 |
|
||||||
|
|
||||||
|
### 3.1 检测延迟
|
||||||
|
|
||||||
|
```
|
||||||
|
正常路径: CAP_OK → cjq_srv(立即) → 判定进出车
|
||||||
|
阻塞路径: CAP_OK → 等待 ≤4.3ms → cjq_srv → 判定进出车
|
||||||
|
|
||||||
|
额外延迟: ≤4.3ms
|
||||||
|
```
|
||||||
|
|
||||||
|
进出车检测本身需要 **3 次连续确认 ≈ 26ms**(ENTRY_CONFIRM=3 × 8.74ms)。
|
||||||
|
|
||||||
|
4.3ms 额外延迟 / 26ms 确认窗口 = **+16%**。
|
||||||
|
|
||||||
|
### 3.2 会丢边沿吗?
|
||||||
|
|
||||||
|
**不会。** CAP_OK 是 TMR0 ISR 置位的标志位,`cjq_srv` 用 `if(loop1_CAP_OK)` 检测。TX 阻塞期间 ISR 照常运行,标志位被置起,TX 结束后 `cjq_srv` 立即处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 极限压测:连续进出车
|
||||||
|
|
||||||
|
假设车辆快速连续进出(罕见,需要车长极短或车速极高):
|
||||||
|
|
||||||
|
```
|
||||||
|
进车检测 → relay ON → TX(4.3ms) → gap(3ms) → 出车检测 → relay OFF → TX(4.3ms)
|
||||||
|
↑ ↑ ↑
|
||||||
|
cjq_srv判定 cjq_srv正常处理 cjq_srv判定
|
||||||
|
```
|
||||||
|
|
||||||
|
每次继电器翻转触发一次 4.3ms TX。两次 TX 之间有 ≥3ms 的 cjq_srv 窗口。
|
||||||
|
|
||||||
|
| 连续翻转次数 | 总 TX 阻塞 | CAP_OK 总延迟 | 影响 |
|
||||||
|
|-------------|-----------|--------------|------|
|
||||||
|
| 1 次 | 4.3ms | +4.3ms | 可忽略 |
|
||||||
|
| 2 次 (一进一出) | 8.6ms | +8.6ms | 可忽略 |
|
||||||
|
| 5 次/秒 | 21.5ms/s | 平均 +4.3ms/次 | 🟢 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 与 9600 波特率的对比
|
||||||
|
|
||||||
|
| | @9600 | @115200 |
|
||||||
|
|--|-------|---------|
|
||||||
|
| 单次 TX | **44.8ms** | **4.3ms** |
|
||||||
|
| 两次 TX 间隔 | ~3ms | ~3ms |
|
||||||
|
| 总干扰窗口 | **~92ms** | **~11.6ms** |
|
||||||
|
| CAP_OK 积压 | **5 次** | **1 次** |
|
||||||
|
| cjq_srv 处理机会 | **TX 之间有 1 次** | TX 之间有 1 次 |
|
||||||
|
| 进出车额外延迟 | +45ms (+170%) | **+4.3ms (+16%)** |
|
||||||
|
|
||||||
|
> @9600 下两次 TX 占满 92ms,`cjq_srv` 只在中间的 3ms 跑了一次,算法面临 5 个 CAP_OK 的积压。@115200 下仅 1 次积压。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 结论
|
||||||
|
|
||||||
|
**@115200,活动上报 + 继电器翻转叠加场景下,线圈检测完全不受实质影响。**
|
||||||
|
|
||||||
|
- 单次 TX 4.3ms < CAP_OK 周期 8.74ms → 不会跨测量窗积压
|
||||||
|
- 两次 TX 必然间隔一次 cjq_srv → 算法不中断
|
||||||
|
- 进出车额外延迟 +4.3ms,相对于 26ms 确认窗口仅 +16%
|
||||||
|
- `loop1_CAP_OK` 是 ISR 置位的标志位,不会因主循环阻塞而丢失
|
||||||
|
|
||||||
|
**如果波特率降到 9600,情况完全不同**——单次 TX 45ms 会积压 5 个 CAP_OK,进出车额外延迟 +170%。这就是为什么 Modbus 默认必须用 115200。
|
||||||
Reference in New Issue
Block a user