2. LIN基础回顾
好,咱们直接进入正题。LIN 2.x 相比 1.x,改动其实不小。很多人觉得 LIN 就是个低成本串口,升级能有多大变化?
我当年第一次看 2.0 规范时,心里也这么想。结果翻到帧结构那页,就发现不对劲了——PID 变了,校验和算法重写了,还多了一套诊断协议。说白了,LIN 2.x 不再是那个“能发数据就行”的协议了,它开始认真考虑可靠性和可维护性。
2.1 帧结构变化:从“发出去”到“发得准”
先看帧结构。LIN 1.x 的帧头很简单:同步间隔 + 同步字节 + PID。到了 2.x,PID 的奇偶校验位算法改了。
为什么会这样?因为 1.x 的奇偶校验覆盖不全,某些 ID 翻转后检测不出来。我在一个项目里就吃过这个亏——从节点收到了错误的 ID,却以为主节点在叫它,结果总线上一通乱抢。
2.x 的 PID 格式如下:
PID[7:0] = ID[5:0] | P0 << 6 | P1 << 7
P0 = ID[0] ⊕ ID[1] ⊕ ID[2] ⊕ ID[4]
P1 = !( ID[1] ⊕ ID[3] ⊕ ID[4] ⊕ ID[5] )
嗯,这里要注意:P1 是取反的。这个改动让 PID 的汉明距离从 2 提升到了 4,能检测出所有单比特和双比特错误。
- PID 奇偶校验算法重写,覆盖更全
- 保留 6 位 ID(0x00–0x3F),共 64 个
- ID 0x3C 和 0x3D 保留给诊断帧
另外,2.x 的数据场长度不再固定为 8 字节。LDF 里可以配置 1–8 字节,帧头里的长度信息由主节点通过调度表隐式传递。这个改动我特别喜欢——很多传感器只需要 1–2 字节数据,硬塞 8 字节纯属浪费带宽。
2.2 校验和算法升级:从经典到增强
校验和是 2.x 另一个大改动。1.x 用的是经典校验和(Classic Checksum),只对数据场做累加。2.x 引入了增强校验和(Enhanced Checksum),把 PID 也加进去了。
| 校验和类型 | 覆盖范围 | 适用场景 |
|---|---|---|
| Classic Checksum | 数据场(1–8 字节) | LIN 1.x 兼容节点 |
| Enhanced Checksum | PID + 数据场 | LIN 2.x 原生节点 |
算法本身没变,还是带进位累加后取反:
uint8_t lin_checksum(uint8_t *data, uint8_t len, uint8_t pid) {
uint16_t sum = 0;
uint8_t i;
// Enhanced: 先加 PID
sum += pid;
for (i = 0; i < len; i++) {
sum += data[i];
if (sum > 0xFF) {
sum -= 0xFF; // 进位回卷
}
}
return (uint8_t)(~sum & 0xFF);
}
你想想看,这个改动意味着什么?同一个数据帧,如果被错误地解析到另一个 ID 上,校验和会直接失败。我在做网关项目时,就靠这个特性拦截了好几次总线错乱——从节点收到错误 PID 后,校验和算出来不对,直接丢弃,不会误动作。
如果总线上混用 1.x 和 2.x 节点,诊断帧(ID 0x3C/0x3D)必须使用 Classic Checksum,因为 1.x 节点不认识 Enhanced。普通数据帧则建议全部使用 Enhanced,除非你有老节点必须兼容。
2.3 诊断机制增强:从“裸数据”到“标准化服务”
LIN 1.x 的诊断?说实话,基本没有。你想读一个节点的状态,得自己定义私有 ID 和协议,每个供应商一套,乱得很。
LIN 2.x 引入了标准诊断协议,基于 ISO 15765-2(就是 CAN 的传输层)裁剪而来。核心是两个诊断帧:
- 主节点请求帧:ID = 0x3C,主节点发,从节点收
- 从节点响应帧:ID = 0x3D,从节点发,主节点收
诊断消息的格式是:
Byte 0: 节点地址 (NAD)
Byte 1: 协议控制信息 (PCI)
Byte 2: 服务标识符 (SID)
Byte 3–7: 服务参数
我记得第一次在 LIN 上跑诊断服务时,心里还挺没底的——这么慢的速率(20 kbps),能干啥?后来发现,诊断主要用于产线和售后,不是跑实时数据,慢点没关系。
常用的诊断服务包括:
| SID | 服务名称 | 用途 |
|---|---|---|
| 0x10 | 诊断会话控制 | 切换会话模式(默认/编程/扩展) |
| 0x22 | 按 ID 读取数据 | 读节点版本、序列号等 |
| 0x2E | 按 ID 写入数据 | 写配置参数、校准值 |
| 0x31 | 例程控制 | 启动自检、执行标定 |
我曾经在一个项目中,诊断帧的 NAD 配错了,导致主节点发请求后,两个从节点同时响应,总线直接崩溃。记住:NAD 必须唯一,且 0x00 是广播地址,不能用作节点地址。
2.4 知识结构图:LIN 2.x 核心新特性
下面这张图把三个核心变化串起来了,方便你对照理解:
2.5 兼容性实战:混网设计要点
最后聊点实际的。如果你的项目里既有 1.x 节点又有 2.x 节点,怎么办?
我个人的做法是:
- LDF 里明确声明每个节点的协议版本——不要靠猜,2.x 的 LDF 支持
protocol_version字段 - 诊断帧统一用 Classic Checksum——这是规范要求的,也是唯一能让 1.x 节点参与诊断的方式
- 普通帧尽量用 Enhanced Checksum——除非你确定某个从节点只支持 Classic
- 主节点必须兼容两种校验和——收到帧后先按 Enhanced 算,失败再按 Classic 算
LIN 2.x 的帧结构更可靠,校验和更安全,诊断更标准。升级到 2.x 不是可选项,是必然趋势——尤其是当你的系统需要 OBD 或产线标定时。