linux_learn/learn/CAN/README.md

8.9 KiB
Raw Blame History

电力二次保护设备 CAN 自定义协议栈 v2.0

一、v2.0 变更说明

基于 v1.0 方案,吸收了以下核心改进:

# 改进项 v1.0 v2.0
1 遥信编码 1-bit (0/1) 2-bit DPS (IEC 61850 双位置: 中间态/分/合/无效)
2 遥测编码 uint16 定点数 IEEE 754 float (通用,无需转换系数)
3 ID 优先级 目标地址在最高位 优先级类别(PRIO)在 bit28-26,紧急报文优先胜出
4 定时 vs 突发 同一帧类型 分离: PRIO_PERIODIC(周期) vs PRIO_BURST(突发)
5 突发机制 直接发送 队列模式: 应用层 push → 协议栈 drain → FD 批量打包
6 批次号 帧序号 bit7-0 批次号: 接收方去重、检测丢帧
7 命令序列号 bit7-0 序列号: 匹配请求与应答

二、v2.0 ID 编码方案

CAN 仲裁规则ID 值越小优先级越高。bit28 最先发送,权重最大。

 28  27  26 | 25  24  23  22  21  20  19 | 18  17  16  15  14  13  12 | 11  10   9   8 |  7   6   5   4   3   2   1   0
┌─────────────┬─────────────────────────────┬─────────────────────────────┬─────────────────┬─────────────────────────────────┐
│  PRIO (3bit) │  目标设备 DST_ADDR (7-bit)  │  源设备 SRC_ADDR (7-bit)   │  MSG_TYPE (4bit) │  批次号/序列号 SEQ (8-bit)       │
│  bit28-26    │  bit25-19                  │  bit18-12                  │  bit11-8         │  bit7-0                          │
└─────────────┴─────────────────────────────┴─────────────────────────────┴─────────────────┴─────────────────────────────────┘

优先级类别 PRIO (bit28-26)

PRIO 名称 最小 ID 范围 用途
000 紧急 0x00000000 保护动作信号、遥控直跳 — 最高优先级
001 突发 0x04000000 遥信变位(COS)、遥测越限 — 事件驱动
010 命令 0x08000000 遥控选择/执行、定值读写、遥调
011 对时 0x0C000000 广播对时、PTP 辅助
100 周期 0x10000000 定时遥信/遥测上送(主动总召)
101 文件 0x14000000 文件传输/固件升级 — 最低业务优先级
110 管理 0x18000000 心跳、链路测试、版本查询
111 保留 0x1C000000 用户扩展

报文类型 MSG_TYPE (bit11-8) — 与 PRIO 组合使用

过程数据类 (PRIO=周期 或 PRIO=突发):

MSG_TYPE 含义
0x0 遥信-定时
0x1 遥测-定时
0x2 遥信-突发 (COS/SOE)
0x3 遥测-突发 (越限)

命令类 (PRIO=命令):

MSG_TYPE 含义
0x0 遥控-选择
0x1 遥控-执行
0x3 定值-写入
0x4 定值-召唤 (读取当前定值, addr=0xFFFF=召唤全部)
0x6 命令ACK
0x7 命令NAK

文件类 (PRIO=文件):

MSG_TYPE 含义
0x0 首帧 (含文件名/总段数/总长度)
0x1 续帧
0x2 尾帧 (含 CRC32)
0x5 文件召唤请求 (主站→从站: 请求上传文件)
0x6 文件召唤就绪 (从站→主站: 文件存在, 即将发送)
0x7 文件召唤拒绝 (从站→主站: 文件不存在等)

批次号/序列号 SEQ (bit7-0)

  • 过程数据: 批次号,每次发送递增 (0-255 循环)接收方用于去重和检测丢帧
  • 命令帧: 序列号,匹配 Request ↔ ACK/NAK
  • 文件帧: 帧序号

三、数据域格式 v2.0

3.1 遥信双位置 (2-bit DPS)

每字节打包 4 个遥信点:

Byte N: [点3.bit1][点3.bit0][点2.bit1][点2.bit0][点1.bit1][点1.bit0][点0.bit1][点0.bit0]

DPS 编码:
  00 = 中间态/不确定    01 = 分(OFF)
  10 = 合(ON)          11 = 无效/故障

定时遥信帧: [起始地址(2B)] [位对数据(N字节)] — FD 模式下可携带 248 个遥信点

3.2 遥测浮点 (IEEE 754)

每个遥测值 4 字节IEEE 754 single-precision大端序。

定时遥测帧: [起始地址(2B)] [float(4B) × N] — FD 模式下可携带 15 个遥测量

3.3 突发打包帧

突发遥信: [点数(1B)] [地址(2B)+状态(1B)+时标ms(4B)] × N — FD 模式每帧最多 9 个点

突发遥测: [点数(1B)] [地址(2B)+浮点值(4B)+时标ms(4B)] × N — FD 模式每帧最多 6 个点

3.4 定值帧 (浮点)

[定值地址(2B)] [float值(4B)] — 与遥测同样的 IEEE 754 格式


四、通讯机制

4.1 定时上送 (主动总召)

定时器触发 (每 500ms 扫描)
    │
    ├── 遍历 XML 配置,检查每个信号的 period_ms 是否到期
    ├── 到期信号通过回调获取当前值
    ├── 打包为 PRIO_PERIODIC 帧(低优先级,不抢占总线)
    └── 批次号递增,接收方可据此检测丢帧

4.2 突发上送 (事件驱动 + 队列打包)

应用层/中断:
    │ 检测到遥信变位或遥测越限
    │ can_protocol_push_yx_burst(addr, state, timestamp)
    │ can_protocol_push_yc_burst(addr, value, timestamp)
    ▼
   突发队列 (lock-free SPSC, 256 深度)

协议栈主循环 (每 5ms):
    │ can_protocol_flush_burst()
    ├── 从队列批量 pop
    ├── FD 模式: 尽可能打包多个点 (遥信9个/帧, 遥测6个/帧)
    ├── PRIO_BURST (高优先级,仅次于紧急)
    └── 短时间内排空队列

4.3 遥控 (选择-返校-执行)

不变,但使用 PRIO_COMMAND + MSG_CMD_YK_* 编码,命令序列号匹配请求和应答。

4.4 定值读写 (双向)

定值写入 (主站→从站):
主站                                  从站
  │── PRIO=CMD, MSG=DZ_WRITE ──────► │
  │    [定值地址(2B) + float值(4B)]    ├── 校验范围 → 写入 Flash
  │◄── MSG=ACK/NAK ────────────────  │

定值召唤 (主站→从站):
主站                                  从站
  │── PRIO=CMD, MSG=DZ_READ ───────► │
  │    [定值地址(2B), 0xFFFF=全部]     ├── 读取当前定值
  │◄── MSG=ACK [addr+float值] ─────── │  (逐条返回)

4.5 文件传输 (双向: 下发 + 召唤)

文件下发 (主站→从站, 如固件升级):
主站                                  从站
  │── FIRST(文件ID, 总段数, 大小) ──► │
  │◄── ACK(就绪) ─────────────────── │
  │── CONT/LAST(段数据, [CRC32]) ──► │
  │◄── ACK(完成) ─────────────────── │

文件召唤 (主站→从站, 如录波文件/日志):
主站                                  从站
  │── READ_REQ(file_id, 文件路径) ──► │
  │                                     ├── 检查文件是否存在
  │◄── READ_ACK(大小, 段数, 文件名) ── │ (存在→就绪)
  │◄── READ_NAK(ERR_FILE_NOT_FOUND) ── │ (不存在→拒绝)
  │◄── FIRST/CONT/LAST... ─────────── │ (自动开始上传)

五、CAN FD 效率 v2.0

突发打包效率

场景 CAN 2.0 (单点/帧) CAN FD (打包) 效率提升
遥信突发 10 个变位 10 帧 2 帧 (9+1) 5×
遥测突发 12 个越限 12 帧 2 帧 (6+6) 6×

定时数据效率

场景 CAN 2.0 CAN FD 提升
16 个遥测量上送 6 帧 2 帧 3×
50 个遥信点上送 7 帧 1 帧 7×

六、文件结构

learn/CAN/
├── README.md                          ← 本文件
├── Makefile
├── include/
│   ├── can_id.h                       ← v2.0 ID 编码 (PRIO + MSG_TYPE)
│   ├── can_frame.h                    ← v2.0 数据格式 (2-bit YX / float YC / burst)
│   ├── can_protocol.h                 ← v2.0 协议栈接口 (burst queue API)
│   └── can_xml_parser.h               ← XML 解析 (支持浮点定值)
├── src/
│   ├── can_id.c
│   ├── can_frame.c                    ← 含突发队列实现
│   ├── can_protocol.c                 ← 含 burst drain + batch 机制
│   └── can_xml_parser.c
├── config/
│   ├── protection_relay.xml           ← 浮点定值示例
│   ├── data_center.xml
│   └── bay_controller.xml
└── app/
    └── test_protocol.c