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 核心新特性

下面这张图把三个核心变化串起来了,方便你对照理解:

LIN 2.x 核心新特性总览 LIN 2.x 协议升级 帧结构变化 校验和算法升级 诊断机制增强 PID 奇偶校验 可变数据长度 Classic Enhanced ID 0x3C/0x3D ISO 15765-2 兼容性要点 诊断帧必须使用 Classic Checksum 普通帧建议使用 Enhanced Checksum

2.5 兼容性实战:混网设计要点

最后聊点实际的。如果你的项目里既有 1.x 节点又有 2.x 节点,怎么办?

我个人的做法是:

  1. LDF 里明确声明每个节点的协议版本——不要靠猜,2.x 的 LDF 支持 protocol_version 字段
  2. 诊断帧统一用 Classic Checksum——这是规范要求的,也是唯一能让 1.x 节点参与诊断的方式
  3. 普通帧尽量用 Enhanced Checksum——除非你确定某个从节点只支持 Classic
  4. 主节点必须兼容两种校验和——收到帧后先按 Enhanced 算,失败再按 Classic 算
一句话总结:

LIN 2.x 的帧结构更可靠,校验和更安全,诊断更标准。升级到 2.x 不是可选项,是必然趋势——尤其是当你的系统需要 OBD 或产线标定时。