Files
CCU621M/app/sub_comm/sub_comm模块说明.md

173 lines
7.4 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.
# sub_comm 模块说明
> 路径:`app/sub_comm/`
> 返回主说明:[README](../../README.md)
## 1. 模块职责
- 主板侧 **USART0** 与副板(CCU621-S)通信:`0x01` 接收 DI/DIP`0x02/0x03/0x04` 下发 DO 与系统/枪信息;
- 维护副板 YK/YX 缓存,供其它模块读写;
- FreeRTOS 周期任务:接收拼帧、发送轮询、DI 超时清零遥信缓存。
## 2. 关键文件
- `sub_comm_task.c`
- `sub_comm_task.h`
## 3. 功能说明
- 任务模型对齐工程其它通信任务(初始化、周期循环、任务锁、喂狗、日志);
- **执行周期 `50ms`**`app_init.c``TASK_SLEEP_MS_50`);
- 对外接口:
- `void v_sub_comm_task(void *arg)`SubComm 线程入口(FreeRTOS
- `void v_sub_comm_yk_set(E_SUB_YK_TYPE e_type, E_CMD e_cmd)`:写入待下发的 DO(YK)缓存;实际下发见 `v_sub_comm_tx_process()` 轮询
- `E_CMD e_sub_comm_yk_get(E_SUB_YK_TYPE e_type)`:读取 YK 缓存
- `U8_T u8_sub_comm_yx_get(E_SUB_YX_TYPE e_type)`:读取最近一次有效 `0x01` 刷新后的 YX/DIP 缓存
## 4. 维护建议
- 校验字段实现上使用 `u16_crc_checksum()`,函数名为历史命名,实质为 **字节累加和**(见 `public_func.c`),与副板 `subcomm_checksum8` 语义一致(结果取低 8 位);
- 可增加链路统计(超时次数、校验失败计数)便于现场诊断;
- 大报文时可评估环形缓冲;当前 `SUBCOMM_RX_BUF_MAX=128` 与副板一致。
## 5. 关联文档
- [plat_comm模块说明](../plat_comm/plat_comm模块说明.md)
- 主索引:[README](../../README.md)
---
## 6. 协议格式说明(副板:USART0,主板<->副板)
本模块使用自定义短帧协议,帧头/帧尾固定,命令码区分 DI 上报与 DO 控制。
### 6.1 帧结构(通用)
单帧总长度:`total_len = 5 + len`(其中 `len` 为数据域长度)
| 字节序号 | 字段 | 说明 |
| --- | --- | --- |
| `[0]` | `HEAD` | 固定帧头:`0x5A` |
| `[1]` | `cmd` | 命令码(DI/DO |
| `[2]` | `len` | 数据域长度:`0~64` |
| `[3..3+len-1]` | `data[]` | 数据域(按 `cmd` 不同含义不同) |
| `[3+len]` | `sum` | 校验:对帧头到数据域的校验结果取低 8 位 |
| `[4+len]` | `TAIL` | 固定帧尾:`0xA5` |
### 6.2 校验字段 `sum`
- 校验计算(发送与接收一致):
- `sum = (uint8_t)u16_crc_checksum(&buf[0], 3 + len)`
- 即对 `[0]~[2+len]`(帧头+cmd+len+data)做 `u16_crc_checksum`,再取低 8 位作为 `sum`
### 6.3 命令码定义
- `0x01``SUBCOMM_CMD_DI_STATUS`
- 方向:副板 -> 主板(上报 DI 状态)
- 数据域长度:工程约定 `len >= 2`(低 16bit 有效)
- `0x02``SUBCOMM_CMD_DO_CTRL`
- 方向:主板 -> 副板(控制副板继电器 DO11~DO16)
- 数据域长度:固定 `len = 2`(两个字节编码 DO11~DO16 + 预留位)
- `0x03``SUBCOMM_CMD_SYS_INFO`
- 方向:主板 -> 副板(下发系统信息)
- 数据域长度:固定 `len = 22`
- `0x04``SUBCOMM_CMD_GUN_INFO`
- 方向:主板 -> 副板(下发充电枪信息)
- 数据域长度:固定 `len = 14`
### 6.4 DI 状态帧(`cmd=0x01`)数据域映射
通信方向:**副板 -> 主板**(副板上报 DI/DIP 状态)。
数据域低 16bit`data[0]` 为低字节,`data[1]` 为高字节)用于承载:
- `bit0 -> YX13`
- `bit1 -> YX14`
- `...`
- `bit9 -> YX22`
- `bit10 -> DIP1`
- `...`
- `bit15 -> DIP6`
当接收未超时(见 6.5)时,上述位值被写入副板缓存 `g_subcomm_ctx.sub_yx.u32_bits`
### 6.5 DO 控制帧(`cmd=0x02`)数据域映射
通信方向:**主板 -> 副板**(主板下发 DO11~DO16 控制命令)。
数据域固定 2 字节(`payload[0]` 为低字节,`payload[1]` 为高字节),承载:
- `bit0 -> DO11(K1)`
- `bit1 -> DO12(K2)`
- `bit2 -> DO13(K3)`
- `bit3 -> DO14(K4)`
- `bit4 -> DO15(K5)`
- `bit5 -> DO16(K6)`
- `bit6 -> RSVD1`(预留遥控位,不参与当前业务)
- `bit7 -> RSVD2`
- `...`
- `bit11 -> RSVD6`
- `bit12~bit15`:保留对齐
### 6.6 系统信息帧(`cmd=0x03`)数据域映射(新增)
通信方向:**主板 -> 副板**(主板周期/按需下发系统状态信息)。
数据域固定 22 字节,字段定义如下:
| 偏移 | 长度 | 字段 | 说明 |
| --- | --- | --- | --- |
| `0` | `12` | `time_str` | 当前时间,ASCII 格式 `YYMMDDhhmmss`,示例:`260101120000` |
| `12` | `1` | `gun_cnt` | 枪数量,单字节 `0~N` |
| `13` | `1` | `led_board_type` | 灯板类型,单字节 `0~N` |
| `14` | `1` | `liquid_cooling_enable` | 液冷使能标志,`0/1` |
| `15` | `1` | `liquid_cooling_type` | 液冷类型;本工程未提供数据来源,默认 `0x00` |
| `16` | `6` | `rsvd` | 预留 6 字节,当前固定 `0x00` |
说明:
- 时间字段为纯 ASCII 数字,不带结束符 `\0`
- `gun_cnt` 建议来自主板当前配置枪数;
- `led_board_type` 建议在后续实现时由板型参数或配置项给出。
- `liquid_cooling_enable` 取值来源:主板系统配置 `u_enable.bit_enable.bit_YeLenEn` 的最低位(约定 `0/1`);
- `liquid_cooling_type` 当前未对接任何系统接口,固定为 `0`(预留给后续协议扩展)。
### 6.7 充电枪信息帧(`cmd=0x04`)数据域映射(新增)
通信方向:**主板 -> 副板**(按枪号下发枪状态信息)。
数据域固定 14 字节,字段定义如下:
| 偏移 | 长度 | 字段 | 说明 |
| --- | --- | --- | --- |
| `0` | `1` | `gun_no` | 充电枪号,单字节,取值 `1/2` |
| `1` | `1` | `gun_link` | 枪连接状态,`0` 未连接,`1` 已连接 |
| `2` | `1` | `charge_state` | 充电状态,取 `flow_interface.c``e_flow_real_state``u16_flow_put_data(...E_FLOW_PUT_DATA_GUN_REAL_STATE...)` |
| `3` | `1` | `led_state` | 指示灯状态,枚举参考 `E_LED_STATE_TYPE``0`绿常亮、`1`绿闪、`2`红常亮、`3`红闪、`4`黄常亮、`5`黄闪 |
| `4` | `1` | `fault_alarm_flag` | 故障告警标志:`0`无、`1`故障、`2`告警 |
| `5` | `1` | `soc` | 充电 SOC,单字节 `0~100` |
| `6` | `8` | `rsvd` | 预留 8 字节,当前固定 `0x00` |
### 6.8 发送节拍与接收超时
> 说明:当前 `sub_comm_task.c` 中 DO/信息帧发送节拍由 SubComm 线程 `50ms` 周期的轮询位移决定,而不是由某个固定 `SUBCOMM_CMD_PERIOD_MS` 常量直接控制。
- DO 控制帧 `0x02`
-`v_sub_comm_tx_process()` 中通过 `s_send_turn` 轮询发送;
- 当 SubComm 任务周期为 `50ms` 时,`0x02` 下发约为 `100ms/次`(偶数执行周期发送)。
- 系统信息 `0x03` / 枪信息 `0x04`
-`0x02` 轮流发送;
- 轮询顺序为:`0x03`(系统)-> `0x04`(枪1-> `0x04`(枪2,若配置存在)-> 下一轮。
- DI 接收超时(离线判断):
- `SUBCOMM_DI_TIMEOUT_MS = 5000ms`
- 若超过该时间未收到有效 DI 状态帧(`cmd=0x01`),则清零副板 YX/DIP 缓存,避免使用过期状态。
### 6.9 收发处理流程(概览)
- 接收端:
- 从 USART0 FIFO 尽可能读取数据追加到 `rx_buf`(支持粘包/残包)。
-`while (u8_sub_comm_try_parse_one_frame() != 0) {}` 中循环解帧,校验失败则丢弃 1 字节重新同步。
- 处理策略:当前接收侧仅对 `cmd=0x01` 的 DI 状态帧刷新 YX/DIP 缓存,其它 `cmd` 默认不落业务缓存。
- 发送端:
- 上层通过 `v_sub_comm_yk_set()` 仅修改副板 YK 缓存位图;串口下发由副板通信任务周期性执行。