Files
DLD154Pro/docs/ble-modbus-concurrent-analysis.md
wangfq 25401c5cf3 docs: BLE+Modbus 双通道并发资源分析
关键发现:
- BLE TX 不阻塞CPU (CH59x 射频DMA自主发送), Modbus TX 阻塞4.3ms
- 两者使用不同硬件 (2.4GHz RF vs UART0), 无资源冲突
- BLE RF ISR 优先级最高, 可抢占 rs485_send 忙等 → BLE连接不中断
- 双通道全开 CPU 44.5%, 余量55%
- 同一迭代最坏: BLE准备(2ms) + Modbus TX(4.3ms) = 6.3ms
- 两者事件触发同源(继电器翻转), 在同一迭代内顺序处理
2026-07-30 18:06:53 +08:00

182 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BLE 动态上报 + Modbus 主动上报 并发场景 — MCU 资源占用分析
> 场景:蓝牙小程序开启动态上报,同时 RS485 Modbus 主动上报使能
> 波特率:115200 (Modbus) | BLE 连接间隔:3050ms(手机协商)
---
## 1. 关键架构差异:BLE 不阻塞 vs Modbus 阻塞
```
┌─────────────────────────────────────────────────────┐
│ BLE 动态上报 │
│ ┌─────────────────────────────────────────────┐ │
│ │ poll_dbn_ble() → report_sens_acs() │ │
│ │ → usart_packet_processing_acs_loop() │ │
│ │ → 准备 BLE 缓冲区 (1–2ms,纯内存操作) │ │
│ │ → 通知 BLE 栈 "有数据要发" │ │
│ │ → 返回(不阻塞) │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ TMOS_SystemProcess() → BLE 栈调度 │
│ ┌─────────────────────────────────────────────┐ │
│ │ BLE RF ISR → DMA 搬数据 → 2.4GHz 无线发送 │ │
│ │ (硬件自主,CPU 不参与传输) │ │
│ └─────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────┤
│ Modbus 主动上报 │
│ ┌─────────────────────────────────────────────┐ │
│ │ modbus_poll() → send_full_data() │ │
│ │ → rs485_send(43B) │ │
│ │ → 逐字节 while(FIFO空) 忙等 │ │
│ │ → 4.3ms CPU 锁死 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
```
**BLE 传输不占用 CPU**——CH59x 的 BLE 硬件用 DMA 把数据从 RAM 搬到 RF FIFOCPU 只需准备缓冲区。Modbus UART 没有 DMACPU 逐字节忙等。
---
## 2. 两者"同时开火"的最坏情况
BLE 事件上报和 Modbus 事件上报的触发点是同一个:**继电器翻转**。
```
cjq_srv() 检测到进车
→ loop1_VD_FLAG = 1
→ g_loop_acs_info.flag_event = 1 ← BLE 事件触发
→ relay1_state 翻转 ← Modbus 事件触发
```
同一个主循环迭代内:
```
Main_Circulation:
TMOS_SystemProcess() ~1.5ms
poll_dbn_ble()
→ report_sens_acs()
→ flag_event == 1
→ usart_packet_processing_acs_loop(1) ~2ms ← BLE: 准备缓冲区
cjq_srv() ~1ms
opt_input_poll() ~0.3ms
modbus_poll()
→ modbus_report_schedule()
→ relay 翻转!
→ send_full_data() 4.3ms ← Modbus: CPU 忙等 TX
─────────────────────────────────────────
本次迭代总耗时: ~9.1ms
```
9.1ms 接近但小于 CAP_OK 测量窗 (8.74ms),在临界线上——最多积压 1 次 CAP_OK。
---
## 3. 持续负载量化
### 3.1 每秒 CPU 时间分解
| 任务 | 频率 | 单次 | 每秒 CPU |
|------|------|------|---------|
| 主循环基础 (TMOS+poll+cjq+opto) | ~114次/s (每个 CAP_OK) | 3.4ms | **388 ms/s** |
| BLE 事件上报 | ~4次/s (2进2出) | 2ms | **8 ms/s** |
| BLE 周期上报 | ~1.7次/s (600ms) | 2ms | **3 ms/s** |
| Modbus 活动 TX | ~6.7次/s (150ms) | 4.3ms | **29 ms/s** |
| Modbus 事件 TX | ~4次/s | 4.3ms | **17 ms/s** |
| **合计** | | | **445 ms/s (44.5%)** |
### 3.2 与纯 Modbus 对比
| 场景 | CPU 占比 | 增量 |
|------|---------|------|
| 仅线圈检测 (无任何上报) | ~39% | 基线 |
| + Modbus 主动上报 | ~42% | +3% |
| + BLE 动态上报 | **~45%** | +3% |
| 余量 | **55%** | 🟢 |
---
## 4. BLE 周期上报的间隔细节
```c
// TMR1 ISR (每 5ms):
if (g_dbn_ble_state_acs_enable.enable)
g_loop_acs_info.report_counter++;
// poll_dbn_ble (主循环):
if (g_loop_acs_info.report_counter >= 120) // 120 × 5ms = 600ms
usart_packet_processing_acs_loop(0); // 周期上报
```
BLE 周期 600msModbus 活动 150ms/空闲 800ms,两者不同步——大部分时间不会在同一迭代中同时触发。
---
## 5. 极限压测:连续进出车 + 双通道全开
```
每秒 2 辆车进出 (4 次继电器翻转):
BLE 事件 TX × 4 = 8 ms
Modbus 事件 TX × 4 = 17 ms
Modbus 活动 TX × 7 = 29 ms
BLE 周期 TX × 2 = 3 ms
cjq_srv × 114 = 388 ms
─────────────────────────
合计 445 ms/s (44.5% CPU)
```
**结论:55% CPU 余量,远未触及瓶颈。**
---
## 6. 真正的瓶颈是什么?
不是 CPU,是 **Modbus TX 期间的 BLE 连接维护**
BLE 连接需要定期交换链路层包(Connection Event)。连接间隔由手机端协商,通常 30–50ms。
```
Time: 0 10 20 30 40 50 ms
BLE: [CE] [CE] [CE] ← 每 30ms 一次
Modbus: [══ TX 4.3ms ══] ← 阻塞期
```
BLE Connection Event 在 ISR 上下文中处理——**射频 ISR 优先级高于主循环**。即使 Modbus TX 正忙等在 UART FIFO 上,BLE ISR 仍能抢占 CPU 完成连接维护。
CH59x 中断优先级:
```
RF (BLE) > TMR0 (线圈) > TMR1 (5ms) > UART0 > 主循环
↑ ↑
抢占一切 被所有人抢占
```
**BLE RF ISR 可以抢占 rs485_send 的忙等循环**。BLE 连接不会因 Modbus TX 断开。
---
## 7. 内存压力
| 缓冲区 | 大小 | 用途 |
|--------|------|------|
| BLE notify buffer | ~200B | `g_notify_buftemp` — BLE 上报数据暂存 |
| BLE response buffer | ~200B | `g_buf_ble_response` — 命令响应 |
| Modbus TX buffer (栈) | 43B | `send_full_data` 局部变量 |
| Modbus data buffer (栈) | 255B | `handle_read_*_regs` 响应组装 |
| RX buffer | 16B | `_rx_buf` (与 700BS 共享) |
BLE 和 Modbus 使用独立的缓冲区,不共享、不竞争。栈峰值约 350B(Modbus 调用链最深),BLE 用全局缓冲。
---
## 8. 总结
| 维度 | 评估 | 说明 |
|------|------|------|
| **CPU** | 🟢 充裕 | 双通道全开 44.5%,余量 55% |
| **BLE 连接** | 🟢 安全 | RF ISR 优先级最高,可抢占 Modbus TX |
| **线圈检测** | 🟢 安全 | 最坏迭代 9.1ms,积压 ≤1 次 CAP_OK |
| **硬件冲突** | 🟢 无 | BLE=2.4GHz RF+DMAModbus=UART0,不同外设 |
| **内存** | 🟢 充裕 | 独立缓冲,栈增量可忽略 |
| **TX 叠加** | 🟢 轻微 | BLE 不阻塞,Modbus 4.3ms,同一迭代 BLE+Modbus = 6.3ms |