modbus 协议分析

BodBus 协议字段详细分析

BodBus (Body Bus) 协议是用于汽车车身电子系统通信的专用协议,不同厂商的实现可能有所差异,但通常包含以下核心字段:

基本帧结构

一个典型的BodBus消息帧包含以下字段:

[起始符] [目标地址] [源地址] [控制字段] [数据长度] [数据字段] [校验和] [结束符]

各字段详细说明

1. 起始符 (Start Byte)

  • 长度: 1字节
  • 功能: 标识帧的开始
  • 典型值: 0x55 或 0x7E
  • 特点:
    • 帮助接收方同步
    • 通常选择不常见于数据部分的字节模式

2. 地址字段

  • 目标地址 (Destination Address)

    • 长度: 1字节
    • 功能: 标识目标ECU
    • 范围: 0x00-0xFE (0xFF通常为广播地址)
  • 源地址 (Source Address)

    • 长度: 1字节
    • 功能: 标识发送方ECU
    • 范围: 0x00-0xFE

3. 控制字段 (Control Field)

  • 长度: 1字节
  • 子字段:
    • 帧类型 (2位):
      • 00: 数据帧
      • 01: 远程帧(请求数据)
      • 10: 错误帧
      • 11: 特殊控制帧
    • 优先级 (2位): 消息优先级(0-3)
    • 应答要求 (1位): 1=需要应答
    • 保留位 (3位): 通常为0

4. 数据长度 (Data Length)

  • 长度: 1字节
  • 功能: 指示数据字段的字节数
  • 范围: 0-8字节(典型值)

5. 数据字段 (Data Field)

  • 长度: 可变(由数据长度字段决定)
  • 功能: 携带实际有效载荷
  • 特点:
    • 通常采用小端格式
    • 可能包含子协议标识符

6. 校验和 (Checksum)

  • 长度: 1字节
  • 算法:
    • 常用8位异或校验
    • 或8位累加和
  • 计算范围: 通常从目标地址到数据字段最后一个字节

7. 结束符 (End Byte)

  • 长度: 1字节
  • 典型值: 0xAA 或 0x0D
  • 功能: 标识帧结束

扩展字段 (某些实现中可能包含)

1. 消息序列号

  • 长度: 1字节
  • 功能: 用于消息跟踪和重复检测

2. 时间戳

  • 长度: 2-4字节
  • 功能: 记录消息发送时间

3. 安全字段

  • 长度: 1-2字节
  • 功能: 包含CRC或简单加密标识

协议示例分析

示例帧(十六进制):

7E 12 34 05 02 41 42 78 AA

解析:

  1. 7E - 起始符
  2. 12 - 目标地址(ECU 0x12)
  3. 34 - 源地址(ECU 0x34)
  4. 05 - 控制字段(数据帧,优先级1,需要应答)
  5. 02 - 数据长度(2字节)
  6. 41 42 - 数据内容("AB")
  7. 78 - 校验和(0x12^0x34^0x05^0x02^0x41^0x42)
  8. AA - 结束符

特殊消息类型

  1. 广播消息:

    • 目标地址=0xFF
    • 所有节点都应接收但不必应答
  2. 诊断消息:

    • 控制字段特定值
    • 数据字段包含诊断命令和参数
  3. 网络管理消息:

    • 用于ECU睡眠/唤醒控制
    • 通常具有最高优先级

协议特点总结

  1. 效率优化:

    • 紧凑的帧结构(通常10字节以内)
    • 最小化协议开销
  2. 可靠性机制:

    • 校验和错误检测
    • 可选的应答机制
    • 部分实现有重传机制
  3. 实时性考虑:

    • 优先级字段支持关键消息优先传输
    • 典型传输延迟<10ms
  4. 扩展性:

    • 通过控制字段支持多种消息类型
    • 数据字段可容纳不同子协议

实际应用中,应参考具体车型或ECU供应商提供的协议规范,因为不同实现可能在字段长度、位置和含义上有所差异。

注释解析:MODBUS RTU CRC校验计算 C#代码

// 计算MODBUS RTU协议的CRC校验值
// 参数:
//   buf - 待计算的数据字节数组
//   len - 要计算的数据长度
// 返回值:
//   字符串形式的CRC校验值(高低字节已交换)
String ModRTU_CRC(byte[] buf, int len)
{
    // 初始化CRC寄存器为0xFFFF(MODBUS CRC16标准初始值)
    UInt16 crc = 0xFFFF;

    // 遍历数据缓冲区中的每个字节
    for (int pos = 0; pos < len; pos++)
    {
        // 1. 将当前数据字节与CRC寄存器进行异或运算
        crc ^= (UInt16)buf[pos];  // XOR byte into least sig. byte of crc

        // 2. 对每个字节的8位进行处理
        for (int i = 8; i != 0; i--)
        {   
            // 检查最低位(LSB)是否为1
            if ((crc & 0x0001) != 0)
            {      
                // 如果LSB为1,右移一位并与多项式0xA001进行异或
                crc >>= 1;         // 右移一位
                crc ^= 0xA001;     // 与MODBUS多项式(0x8005的反转)异或
            }
            else
            {
                // 如果LSB为0,仅右移一位
                crc >>= 1;         // 仅右移一位
            }
        }
    }

    // 将CRC值转换为16进制字符串
    string result = crc.ToString("X"); 
    
    // 确保结果是偶数长度(前面补0)
    if (result.Length % 2 == 1)
    {
        result = "0" + result;
    }

    // MODBUS协议要求CRC的高低字节交换位置
    string strLine = "";
    for(var i = 0; i < result.Length; i+=2)
    {
        // 将字节顺序反转(高低字节交换)
        strLine = result.Substring(i, 2) + strLine;
    }

    return strLine;
}

关键点说明:

  1. CRC初始化:MODBUS RTU CRC16使用0xFFFF作为初始值

  2. 核心计算过程

    • 对每个输入字节与CRC寄存器进行异或
    • 对每个字节的8位分别处理
    • 如果LSB为1,右移后与多项式0xA001异或
    • 如果LSB为0,仅右移
  3. 多项式说明

    • 0xA001是标准CRC-16多项式0x8005的反转(bit-reversed)形式
    • 这是MODBUS RTU协议的特定要求
  4. 字节顺序处理

    • MODBUS协议要求CRC值的高字节和低字节交换位置
    • 最后一段代码实现了这个交换功能
  5. 输出格式

    • 返回字符串形式的16进制表示
    • 确保偶数长度(不足补0)
    • 高低字节已交换

这个实现严格遵循MODBUS RTU协议的CRC16校验标准,可直接用于MODBUS RTU通信的校验计算。

AI绘图