一、从全链路认识卫星通信系统
当前项目中的通信链路,可以分成几个层次理解:
物理通信
CAN-A / CAN-B
↓
CAN 总线协议
↓
CAN Frame
├─ CAN ID
├─ DLC
└─ Data
↓
项目自定义传输协议
├─ 单帧
└─ 复合帧 Start / Middle / End
↓
完整业务数据包
├─ 类型指示
├─ APID
├─ 命令码
└─ Payload
↓
具体业务
├─ 遥控
├─ 遥测
└─ 时间广播
最重要的是分清:
CAN 本身
→ 负责“数据怎么可靠地在总线上传输”
项目协议
→ 负责“这些 CAN 数据具体是什么意思”
因此分析一条项目 CAN 报文时,推荐始终按照:
CAN ID
↓
DLC
↓
Data
↓
是否需要复合帧重组
↓
类型 / APID / 命令码
↓
具体业务
来理解。
二、CAN 如何实现可靠的总线通信
CAN 是什么
CAN(Controller Area Network)是一种总线通信协议。
它不仅规定了差分信号传输,还包含:
- 帧格式
- 总线仲裁
- CRC
- ACK
- 错误检测
- 自动重发
- 位填充
- 位同步
因此 CAN 比 RS-422 这类单纯的电气接口标准更加完整。
CAN 为什么没有时钟线也能同步
CAN 没有单独的时钟线。
每个 CAN 节点都有自己的晶振:
节点 A:40.000 MHz
节点 B:39.998 MHz
节点 C:40.003 MHz
晶振不可能完全一致,如果各节点一直使用自己的时钟计数,采样位置就会逐渐发生偏移。
CAN 的解决方式是:
各节点使用自己的晶振产生本地 bit 时钟,同时利用总线上的电平变化边沿不断修正自己的采样位置。
所以 CAN 同步的并不是:
把所有节点晶振变成一样
而是:
不断修正 bit timing / 采样时刻
显性、隐性与边沿
CAN 中:
显性 Dominant = 0
隐性 Recessive = 1
当总线发生:
1 → 0
或者:
0 → 1
就产生了一个边沿。
例如:
bit: 1 1 0 0 1
总线:───────┐ ┌─────
│ │
└───────┘
↑ ↑
边沿 边沿
CAN 控制器会比较:
预计边沿位置
VS
实际边沿位置
从而判断自己的采样时间是否出现偏移。
TQ
例如 CAN 波特率为:
500 kbit/s
一个 bit 的时间:
1 / 500000
= 2 μs
CAN 控制器会继续把一个 bit 划分成多个:
TQ = Time Quantum
例如:
1 bit = 16 TQ
那么:
1 TQ = 2 μs / 16
= 125 ns
一个 bit 可以表示为:
| Sync_Seg | Prop_Seg | Phase_Seg1 | Phase_Seg2 |
也常简化成:
| Sync |---------- TSEG1 ----------|--- TSEG2 ---|
↑
Sample Point
采样点
接收节点最终要做的事情就是:
在正确的 Sample Point 判断当前总线到底是 0 还是 1。
重同步 Resynchronization
假设节点预计 bit 边界在:
↓
----------|----------------
实际却检测到:
↓预计
----------|---↓------------
实际
CAN 控制器就会调整 Phase Segment,使之后的 Sample Point 重新靠近正确位置。
这个过程叫:
Resynchronization
重同步
SJW
SJW:
Synchronization Jump Width
同步跳转宽度
表示:
一次重同步允许修正的最大 TQ 数量。
例如:
SJW = 2 TQ
可以把同步过程理解成:
检测到有效边沿
↓
计算实际边沿和预计边沿的偏差
↓
得到 Phase Error
↓
受到 SJW 最大调整范围限制
↓
调整 Phase Segment
↓
修正后续采样点
Hard Synchronization 与 Resynchronization
Hard Synchronization
主要发生在一帧 CAN 刚开始的时候,也就是:
SOF
总线空闲:
111111111111
开始发送:
111111111110
↑
SOF
这个明显的 1 → 0 边沿可以作为一帧的同步起点。
Resynchronization
进入一帧之后,CAN 控制器继续利用数据中的有效边沿进行微调。
所以可以简单理解:
SOF
↓
硬同步
↓
开始接收 CAN Frame
↓
过程中不断检测边沿
↓
重同步
↓
持续修正采样点
Bit Stuffing
如果发送:
000000000000000
很长时间没有电平变化,就缺少用于同步的边沿。
因此 CAN 使用:
Bit Stuffing
位填充
在相应帧区间连续出现 5 个相同 bit 后,插入一个相反 bit。
例如:
00000 1 00000
↑
Stuff Bit
接收端知道这个规则,会自动删除 Stuff Bit,因此不会影响真正的数据。
经典 CAN 中,普通位填充主要从:
SOF
↓
Arbitration Field
↓
Control Field
↓
Data Field
↓
CRC Sequence
三、CAN Frame:应用程序真正接触的数据边界
经典 CAN 数据帧可以简化成:
┌─────┬────────────┬─────┬─────┬────┬─────┬────────┬─────┬─────┬─────┐
│ SOF │ Identifier │ RTR │ IDE │ r0 │ DLC │ Data │ CRC │ ACK │ EOF │
└─────┴────────────┴─────┴─────┴────┴─────┴────────┴─────┴─────┴─────┘
各字段可以先这么记:
| 字段 | 含义 |
|---|---|
| SOF | 一帧开始 |
| Identifier | CAN ID |
| RTR | 数据帧还是远程帧 |
| IDE | 11 bit ID 还是 29 bit ID |
| r0 | 保留位 |
| DLC | Data 有多少有效字节 |
| Data | 真正的数据 |
| CRC | 检测传输错误 |
| ACK | 是否有其他节点正确收到 |
| EOF | 一帧结束 |
SOF
SOF = Start Of Frame
占:
1 bit
作用:
- 表示一帧开始;
- 提供 Hard Synchronization 的边沿。
RTR
RTR = Remote Transmission Request
经典 CAN 可以简单理解为:
RTR = 0
→ Data Frame
RTR = 1
→ Remote Frame
Remote Frame 可以粗略理解成:
“请把这个 CAN ID 对应的数据发给我。”
IDE
IDE = Identifier Extension
用于区分:
IDE = 0
→ 11 bit 标准 CAN ID
IDE = 1
→ 29 bit 扩展 CAN ID
当前项目使用的是:
11 bit 标准 CAN ID
DLC
DLC = Data Length Code
表示:
当前 CAN Frame 的 Data 区域有多少有效字节。
经典 CAN:
DLC = 0 ~ 8
例如:
CAN ID = 0x123
DLC = 4
DATA = 11 22 33 44
说明 Data 中只有 4 Byte。
注意:
DLC = 8
表示:
Data = 8 Byte
并不是:
整个 CAN Frame = 8 Byte
完整 CAN Frame 还有 CAN ID、CRC、ACK、EOF 等字段。
CRC
CRC = Cyclic Redundancy Check
作用:
发送端
计算 CRC
↓
发送 Data + CRC
↓
接收端重新计算 CRC
↓
和收到的 CRC 比较
不同说明报文传输发生错误。
ACK
ACK 的核心是 ACK Slot。
发送节点在 ACK Slot 放:
隐性 1
如果至少一个节点正确接收到这一帧,会发送:
显性 0
因为显性 0 会覆盖隐性 1(线与),所以发送节点最终看到 0,就知道:
至少有一个 CAN 节点正确收到了这一帧。
但注意:
CAN ACK 成功
≠
上层业务处理成功
ACK 只说明 CAN 链路层正确接收。
EOF
EOF = End Of Frame
经典 CAN:
EOF = 7 bit
表示当前 CAN Frame 结束。
四、从 CAN ID 到完整业务包
CAN ID 的位域设计
项目协议首先利用 11 bit CAN ID 表达节点地址、帧类型和分片状态。
11 bit CAN ID
标准 CAN ID:
ID10 ID9 ID8 ID7 ID6 ID5 ID4 ID3 ID2 ID1 ID0
当前项目进一步定义成:
ID10~6 ID5~2 ID1~0
┌───────────┬─────────────┬───────────┐
│ nodeAddr │ frameType │ frameInfo │
│ 5 bit │ 4 bit │ 2 bit │
└───────────┴─────────────┴───────────┘
也就是:
5 + 4 + 2 = 11 bit
编码
CAN_ID = ((nodeAddr & 0x1F) << 6) |
((frameType & 0x0F) << 2) |
(frameInfo & 0x03)
其中:
& 0x1F
→ 保留 nodeAddr 的低 5 bit
& 0x0F
→ 保留 frameType 的低 4 bit
& 0x03
→ 保留 frameInfo 的低 2 bit
左移负责把字段移动到对应位置:
nodeAddr << 6
frameType << 2
frameInfo 不需要移动
最后:
|
负责把几个字段拼成完整的 11 bit CAN ID。
解码
反过来:
nodeAddr = (CAN_ID >> 6) & 0x1F
frameType = (CAN_ID >> 2) & 0x0F
frameInfo = CAN_ID & 0x03
本质就是:
编码:
业务字段 → CAN ID
解码:
CAN ID → 业务字段
单帧、复合帧与重组状态机
当业务数据超过 Classical CAN 单帧 8 Byte 的上限时,项目协议需要自行定义分片规则。
当前项目使用 CAN ID 最低两位表示:
| ID1~ID0 | 含义 |
|---|---|
00 |
单帧 |
01 |
起始帧 Start |
10 |
中间帧 Middle |
11 |
尾帧 End |
注意:
复合帧不是 CAN 标准定义,而是当前项目建立在 CAN 之上的应用层分片协议。
为什么需要复合帧
Classical CAN:
单帧 Data 最大 8 Byte
如果一个完整业务包有:
30 Byte
就必须拆成:
完整 Payload
↓
Start
↓
Middle
↓
Middle
↓
End
接收端再重新拼回 30 Byte。
起始帧
例如:
00 1E + payload[0:6]
其中:
00 1E
按照大端解析:
0x001E = 30
表示整个复合 Payload 长度为:
30 Byte
所以 Start Frame 的 8 Byte:
Byte0 Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7
00 1E P0 P1 P2 P3 P4 P5
└──────┘
总长度
大端 Big Endian
大端就是:
多字节整数的高有效字节放在前面。
例如:
0x1234
大端:
12 34
小端:
34 12
Go 中常见:
binary.BigEndian.Uint16(data)
binary.BigEndian.Uint32(data)
注意:
“大端”描述的是一个多字节字段内部的字节排列,并不是说整个 CAN Frame 都有统一的大端属性。
相邻帧 ≤ 0.5ms
协议要求复合帧相邻 CAN Frame:
上一帧 EOF
↓
≤ 0.5ms
↓
下一帧 SOF
目的是:
- 减少一个复合包占用的总时间;
- 降低接收端重组超时概率;
- 保证一定实时性。
但:
≤ 0.5ms并不意味着中间绝对不会出现其他 CAN Frame。
其他节点的帧可以插进来
例如可能出现:
A_Start
A_Middle
B_Frame
A_Middle
A_End
这是正常的。
原因是 CAN 每发送完一帧后,总线都会重新仲裁。
接收端可以根据:
nodeAddr
分别维护不同节点的重组状态:
rxState[nodeA]
rxState[nodeB]
真正危险的是:
同一个节点同时交叉发送两个复合包
例如:
A包:A1 A2 A3
B包:B1 B2 B3
发送:
A1 B1 A2 B2 A3 B3
如果协议中没有额外 Message ID / Sequence ID,就很难判断每个 Middle 属于哪个包。
因此当前协议更可能依赖:
- 主从轮询;
- 同节点同一时间只有一个复合包;
- Start / Middle / End 状态机;
- 超时清理。
CAN ID 与 APID 的职责边界
CAN ID 描述当前 CAN Frame,APID 描述重组后的业务数据,两者属于不同层次。
这是整个项目里非常重要的一层。
CAN ID
属于:
CAN Frame / 总线层
回答:
这是哪个节点的?
是什么 frameType?
是单帧还是 Start / Middle / End?
APID
属于:
完整业务数据包
APID:
Application Process Identifier
应用过程识别字
当前协议中为:
11 bit
进一步划分:
APID
┌──────────────┬─────────────┐
│ 模块标识 7bit │ 数据类型4bit │
└──────────────┴─────────────┘
主要回答:
这是哪个业务模块的数据?
具体是哪一种遥控 / 遥测?
因此可以记成:
CAN ID
→ CAN Frame 是谁的、怎么传
APID
→ 完整 Payload 到底是什么业务
完整业务包的识别顺序
完整数据包中可以存在:
版本号
类型指示
副导头标志
APID
序列控制
包长
应用数据
校验
解析顺序可以理解成:
复合帧重组完成
↓
得到完整业务包
↓
解析包主导头
↓
类型指示
↓
遥控 TC / 遥测 TM
↓
APID
↓
具体模块 + 数据类型
↓
解析应用数据
因此存在多个层级:
CAN ID
→ 粗分类
类型指示
→ 遥控还是遥测
APID
→ 具体是什么业务数据
Payload
→ 真正的参数和值
五、星上节点、设备管理与遥控遥测
OBC 与主从节点
OBC
OBC = On-Board Computer
一般可以翻译为:
- 星载计算机
- 星务计算机
- 星上计算机
在通信关系中可以理解成中央主控:
OBC
CAN 主节点
│
┌─────────┼─────────┐
↓ ↓ ↓
导航 热控 载荷
从节点 从节点 从节点
OBC 通常负责:
- 发起遥测巡检;
- 下发遥控;
- 收集遥测;
- 时间管理;
- 总线管理;
- 故障处理;
- 任务调度。
主节点与从节点
这里的“从节点”说的是:
CAN 通信中的角色。
并不是:
协议解析代码运行在哪个进程
主节点通常主动发起通信:
OBC → 导航模块:给我遥测
导航模块 → OBC:返回遥测
所以所谓“巡检”可以理解成:
OBC 周期性轮询各个从节点获取遥测数据。
5ms 应答
当前协议要求:
从节点最大应答时间 ≤ 5ms
可以理解:
主节点发请求
↓
等待
↓
≤ 5ms?
/ \
是 否
↓ ↓
正常 超时
↓
恢复流程
“恢复流程”不是 CAN 标准统一定义,而属于当前项目的应用层协议。
可能涉及:
- 清理当前接收状态;
- 丢弃未完成复合帧;
- 重置状态机;
- 重新发起请求;
- 多次失败后记录通信异常。
具体恢复动作仍需要以完整协议规定为准。
SMU 的位置与职责
基本概念
SMU(Satellite Management Unit,卫星管理单元)是卫星中的设备管理与控制模块。
主要负责:
- 遥控指令执行
- 遥测数据采集
- 卫星设备状态管理
- 设备健康监测
简单理解:
SMU 就是卫星内部负责管理和控制各类设备的单元。
SMU 在卫星系统中的位置
典型结构:
地面测控
|
|
OBC
(星载计算机)
|
CAN / RS422
|
SMU
(卫星管理单元)
|
----------------
| | |
电源 传感器 执行设备
其中:
- OBC(On Board Computer):星载计算机,负责任务计算和整体调度
- SMU(Satellite Management Unit):卫星管理单元,负责设备控制和状态管理
SMU 主要功能
遥控执行
OBC 下发遥控指令:
OBC
|
CAN
|
SMU
|
执行设备
例如:
- 打开/关闭设备
- 修改设备参数
- 切换工作模式
遥测采集
SMU 周期采集卫星状态:
例如:
- 电压
- 电流
- 温度
- 设备运行状态
然后通过 CAN 等总线发送给 OBC。
健康监测
SMU 监控卫星设备状态:
例如:
- 温度异常
- 电压异常
- 通信异常
发现异常后:
- 上报告警
- 执行保护动作
- 切换安全模式
SMU 与 OBC 的区别
| OBC | SMU | |
|---|---|---|
| 全称 | On Board Computer | Satellite Management Unit |
| 作用 | 计算、任务调度 | 设备管理、控制 |
| 关注点 | 卫星任务怎么执行 | 设备是否正常运行 |
| 接口 | CAN、以太网等 | CAN、RS422、GPIO等 |
简单理解:
OBC:决定卫星要做什么
SMU:负责控制设备完成这些事情
+#### SMU 与 CAN 的关系
卫星内部常通过 CAN 连接:
OBC
|
CAN
|
SMU
|
设备/传感器
CAN 主要用于:
- 遥控指令传输
- 遥测数据传输
- 设备状态交互
因此在卫星项目中:
CAN 协议通常用于 OBC 与 SMU 等卫星设备之间的通信。
遥控 TC 与遥测 TM
遥控 TC(Telecommand)
可以简单理解成:
地面 / 主控
↓
卫星设备
也就是向设备下发:
- 开关机;
- 重启;
- 参数设置;
- 模式切换;
- 任务控制等指令。
遥测 TM(Telemetry)
方向相反:
卫星设备
↓
OBC / 地面
主要用于上报:
- 工作状态;
- 温度;
- 电压;
- 电流;
- 导航数据;
- 软件状态;
- 故障状态等。
为什么遥控经常需要复合帧
原材料中的遥控数据包结构为:
包主导头:6 Byte
应用数据:N Byte
校验: 2 Byte
总长度:
8 + N Byte
当:
N = 0
刚好:
8 Byte
理论上一个 Classical CAN Frame 能装下。
只要:
N > 0
就超过 Classical CAN 的 8 Byte 限制,因此需要复合帧。
例如:
包头 6B
应用数据 10B
校验 2B
--------------
总计 18B
就需要:
Start → Middle → End
六、Linux 下的 CAN 工程实现
从 SocketCAN 到业务处理
材料中的整体处理流程:
CAN-A / CAN-B
↓
Linux can0 / can1
↓
SocketCAN Filter
↓
epoll
↓
ReceiveFrame
↓
HandleFrame
↓
PushCompoundFrame
↓
CanPacketProc
├─ 0x01 → 遥测
├─ 0x07 → 遥控
└─ 0x0B → 时间广播
也就是应用程序主要关心:
CAN ID
DLC
DATA
像:
SOF
Bit Stuffing
CRC
ACK
EOF
Bit Synchronization
这些通常已经由:
CAN Controller
+
Linux CAN Driver
完成。
SocketCAN 过滤规则
项目存在类似:
{ID: 0x340, Mask: 0x7C0}
{ID: 0x7EC, Mask: 0x7FF}
过滤逻辑可以理解成:
(receivedID & mask) == (filterID & mask)
Mask = 0x7C0
0x7C0 = 11111 000000
只比较 CAN ID 高 5 bit。
而当前协议:
ID10~ID6 = nodeAddr
所以:
ID=0x340
Mask=0x7C0
本质上就是:
按节点地址过滤,不关心后面的 frameType 和 frameInfo。
简单理解:
Mask 中为 1
→ 这个 bit 要比较
Mask 中为 0
→ 这个 bit 不关心
Mask = 0x7FF
0x7FF = 11111111111
11 bit 全部比较。
因此:
ID = 0x7EC
Mask = 0x7FF
表示:
只允许 CAN ID 完全等于
0x7EC的报文通过。
Bit Timing 的配置与核验
方式一:让驱动计算
ip link set can0 type can bitrate 500000 sample-point 0.875
表示:
bitrate = 500 kbps
sample point = 87.5%
具体 TQ、Phase Segment 等由驱动计算。
方式二:直接指定 Bit Timing
ip link set can0 type can \
tq 400 \
prop-seg 1 \
phase-seg1 2 \
phase-seg2 1 \
sjw 1
总 TQ:
Sync = 1
Prop = 1
PhaseSeg1 = 2
PhaseSeg2 = 1
----------------
总计 = 5 TQ
每个:
TQ = 400ns
因此:
Bit Time
= 5 × 400ns
= 2μs
所以:
Bitrate
= 1 / 2μs
= 500 kbps
采样点:
(1 + 1 + 2) / 5
= 80%
两次配置实际上是重复设置
两套配置:
| 配置 | 波特率 | Sample Point |
|---|---|---|
bitrate 500000 sample-point 0.875 |
500 kbps | 87.5% |
tq 400 ... |
500 kbps | 80% |
所以:
Bitrate 相同
Sample Point 不同
本质上是在:
对同一个 CAN 接口连续进行了两次 Bit Timing 配置。
联调时不要只看代码,应该读取接口最终状态:
ip -details link show can0
确认:
bitrate
sample-point
tq
prop-seg
phase-seg1
phase-seg2
sjw
最终以实际生效参数为准。
CAN-A / CAN-B 双总线冗余
CAN-A
├─ A_CANH
└─ A_CANL
CAN-B
├─ B_CANH
└─ B_CANL
也就是:
两套独立 CAN 总线。
用途通常是:
正常:
CAN-A 工作
CAN-A 故障:
切换 CAN-B
形成总线级冗余。
七、GNSS、PPS 与 CAN 时间广播
GNSS 提供什么
GNSS
= Global Navigation Satellite System
= 全球导航卫星系统
包括:
- GPS
- 北斗
- Galileo
- GLONASS
GNSS 接收机可以提供:
- 时间;
- 位置;
- 速度;
- 定位状态;
- 可见卫星数量;
- 时间同步状态等。
所谓:
GNSS 遥测
就是:
将 GNSS 接收机获取的时间、位置、速度和工作状态等信息,作为遥测数据提供给其他模块或下传。
PPS 与 CAN 时间码如何配合
PPS
PPS = Pulse Per Second
1PPS 就是:
每秒产生一次脉冲。
当前协议使用:
PPS 下降沿
作为精确整秒时刻。
例如:
PPS ↓ PPS ↓
│ │
└────── 1 second ─────┘
PPS 为什么不能单独完成时间同步
PPS 只能告诉设备:
“现在到整秒了”
却不能告诉设备:
“现在具体是哪一天几点几分几秒”
因此还需要 CAN 时间广播。
两者分别解决:
PPS
→ 精确告诉节点“整秒发生在什么时候”
CAN 时间码
→ 告诉节点“这个整秒到底是多少时间”
所以:
PPS
+
CAN Time Broadcast
=
完整时间同步
为什么不能只使用 CAN 时间广播
CAN Frame 实际什么时候发送出去,会受到:
- CPU 调度;
- CAN 仲裁;
- 总线占用;
- 更高优先级报文;
影响。
例如计划:
12:00:05.000
发送,最终可能:
12:00:05.050
才抢到总线。
因此:
PPS
→ 硬件级精确时间边界
CAN
→ 携带具体时间值
二者结合更加可靠。
当前协议时间要求
材料中的关系是:
PPS 下降沿
↓
精确整秒
│
└──── ≤ 200ms ────┐
↓
CAN 时间广播
秒 + 微秒
也就是说:
CAN 广播中的秒值应该和 PPS 对应的整秒一致,并且时间广播距离 PPS 下降沿不能超过约 200ms。
八、CAN 与 RS-422
RS-422 是:
串行通信电气接口标准。
它主要规定:
电信号怎么传
通常不会规定:
业务 Payload 应该是什么格式
差分传输
典型信号:
TX+
TX-
接收端判断:
Vdiff = TX+ - TX-
而不是只看某一根线相对 GND 的电压。
例如:
正常:
TX+ = 3V
TX- = 1V
差值 = 2V
共同受到 +1V 干扰:
TX+ = 4V
TX- = 2V
差值仍然 = 2V
因此差分传输具有较好的抗共模干扰能力。
可以粗略区分:
RS-232
→ 单端串行接口
RS-422
→ 差分串行接口
CAN
→ 差分物理层 + 完整总线协议
CAN 与 RS-422 的对比
| CAN | RS-422 | |
|---|---|---|
| 是否差分 | 是 | 是 |
| 线路 | CANH/CANL | TX+/TX- |
| 抗干扰 | 强 | 强 |
| 通信方式 | 多节点总线 | 点对点为主 |
| 是否有仲裁 | 有 | 没有 |
| 协议 | 完整CAN协议 | 主要定义物理层 |
| 错误检测 | CRC、ACK、错误状态 | 较弱,需要上层处理 |
九、FPGA 在卫星通信架构中的位置
FPGA 是什么
FPGA:
Field-Programmable Gate Array
现场可编程门阵列
可以简单理解为:
内部数字电路可以通过编程重新配置的芯片。
CPU 是:
固定硬件
+
不断执行软件指令
FPGA 更接近:
通过代码
↓
配置芯片内部逻辑资源
↓
形成需要的数字电路
FPGA 和 CPU 的核心区别
CPU:
读取指令
↓
执行
↓
下一条指令
FPGA:
模块A ──→
模块B ──→ 可以并行工作
模块C ──→
FPGA 的优势主要来自:
并行
+
流水线
+
专用数据通路
而不是单纯依靠更高的 CPU 主频。
FPGA 主要资源
常见:
| 资源 | 作用 |
|---|---|
| LUT | 组合逻辑 |
| Flip-Flop | 保存状态 |
| BRAM | 片上存储 |
| DSP | 乘加等数学运算 |
| Programmable Interconnect | 连接不同逻辑 |
| SerDes 等接口资源 | 高速通信 |
常用 HDL:
Verilog
VHDL
SystemVerilog
HDL 与普通 Go/C 代码最大的区别是:
HDL 主要用于描述“硬件应该长什么样”,而不是描述 CPU 按什么顺序执行指令。
CPU / GPU / FPGA / ASIC
| 类型 | 特征 |
|---|---|
| CPU | 通用性最好,适合复杂控制逻辑 |
| GPU | 大规模并行,适合 AI、矩阵、图形 |
| FPGA | 可重构、低延迟、并行、接口灵活 |
| ASIC | 专用程度最高,性能和能效高,但灵活性最低 |
可以简单记:
CPU
= 通用工人
GPU
= 大量相同类型的并行工人
FPGA
= 可以重新搭建的生产线
ASIC
= 已经焊死的专用生产线
FPGA 在当前产品架构中的价值
卫星相关设备可能需要:
CAN
RS422
RS485
LVDS
SpaceWire
1553B
自定义高速接口
FPGA 很适合位于:
CAN ─────┐
RS422 ───┤
LVDS ────┤
↓
FPGA
↓
PCIe
↓
CPU
负责:
- 接口扩展;
- 协议解析;
- 数据过滤;
- 数据搬运;
- 时间戳;
- 编解码;
- 实时预处理;
- 高速计算。
不同项目只需重新配置 FPGA:
项目 A
4 CAN + 2 RS422
项目 B
2 CAN + 8 RS422 + 1 LVDS
因此 FPGA 很适合实现:
硬件平台尽量通用,针对不同卫星项目通过 FPGA 和软件进行二次适配。
十、把所有概念串成一条链路
把所有概念连起来:
星上 / 地面设备
│
CAN-A / CAN-B
│
↓
CAN Controller
│
┌────────────┴────────────┐
│ │
CAN底层机制 CAN Frame
│ │
同步 / CRC / ACK CAN ID + DLC + DATA
仲裁 / 位填充 │
↓
SocketCAN
│
Filter / epoll
│
↓
CAN ID 解析
┌─────────────┼─────────────┐
↓ ↓ ↓
nodeAddr frameType frameInfo
│
单帧 / 复合帧
│
↓
Payload 重组
│
↓
完整业务数据包
│
┌──────────────┼──────────────┐
↓ ↓ ↓
类型指示 APID 参数
│ │
↓ ↓
遥控 / 遥测 模块 + 数据类型
│
↓
具体业务
核心结论
1. CAN 没有独立时钟线
→ 各节点靠自己的晶振工作
→ 再通过总线边沿不断修正 Sample Point
2. Classical CAN
→ Data 最大 8 Byte
→ DLC 描述 Data 的有效长度
3. CAN ID
→ 当前项目拆成:
nodeAddr + frameType + frameInfo
4. frameInfo
→ 00 单帧
→ 01 Start
→ 10 Middle
→ 11 End
5. 复合帧
→ 是项目应用层协议
→ 不是 CAN 标准自带的机制
6. CAN ID
→ 负责“这帧是谁的、怎么传”
7. APID
→ 负责“完整业务包具体是什么数据”
8. OBC
→ CAN 主节点
→ 发起巡检、下发遥控、收集遥测
9. PPS
→ 给出精确整秒边界
10. CAN 时间广播
→ 给出具体时间值
11. SocketCAN
→ Linux 应用主要处理 CAN ID / DLC / Data
→ CRC、ACK、同步等由 CAN 控制器和驱动处理
12. FPGA
→ 通过编程配置硬件逻辑
→ 适合接口扩展、协议处理、实时并行计算