You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Autosar CRC16-ARC带反射位实现异常,请求问题排查

16位带反射CRC实现问题排查

我在自行实现Autosar CRC库时,计算带反射位的16位CRC函数遇到问题。查过官方文档和相关论坛,还是没找到程序错误。官方测试用例如下:

  • 数据字节(0x00, 0x00, 0x00, 0x00),预期CRC结果0x0000
  • 数据字节(0xF2, 0x01, 0x83),预期CRC结果0xC2E1
  • 数据字节(0x0F, 0xAA, 0x00, 0x55),预期CRC结果0x0BE3

但我的程序输出和预期不符,以下是我的实现代码:

uint32 Reflect(uint32 data, uint8 bit_count)
{
    uint32 reflection = 0;
    for (uint8 bit = 0; bit < bit_count; bit++) 
    {
        if (data & 0x01) 
        {
            reflection |= (1 << ((bit_count - 1) - bit));
        }
        data >>= 1;
    }
    return reflection;
}

uint16 Crc_CalculateCRC16ARC(const uint8* Crc_DataPtr, uint32 Crc_Length, uint16 Crc_StartValue16, boolean Crc_IsFirstCall)
{
    const uint16 Crc_Polynomial = 0x8005; 
    uint16 crcValue = Crc_StartValue16;

    if(Crc_IsFirstCall)
    {
        crcValue = 0xFFFF;
    }

    for (int i = (int)Crc_Length - 1; i >= 0; --i)
    {
        crcValue ^= Reflect(Crc_DataPtr[i], 8) << 8;

        for (uint8 bit = 0; bit < 8; bit++)
        {
            if (crcValue & 0x8000) 
            {
                crcValue = (crcValue << 1) ^ Crc_Polynomial;
            }
            else
            {
                crcValue <<= 1;
            }
        }
    }

    return Reflect(crcValue ^ 0xFFFF, 16);
}

错误分析与修正

代码存在四个关键错误:

  1. 字节处理顺序颠倒:循环从最后一个字节开始处理,而Autosar CRC16 ARC要求按数据的自然顺序(从第一个到最后一个)处理。
  2. 字节异或位置错误:将反射后的字节左移8位异或到CRC高字节,正确做法是直接异或到CRC低字节(反射后的字节按LSB优先处理)。
  3. 多项式未反射:带反射的CRC需使用反射后的多项式,原多项式0x8005反射后应为0xA001。
  4. 最终异或值错误:Autosar CRC16 ARC的最终异或值是0x0000,而非0xFFFF,代码中多做了一次不必要的异或操作。

修正后的代码

uint32 Reflect(uint32 data, uint8 bit_count)
{
    uint32 reflection = 0;
    for (uint8 bit = 0; bit < bit_count; bit++) 
    {
        if (data & 0x01) 
        {
            reflection |= (1 << ((bit_count - 1) - bit));
        }
        data >>= 1;
    }
    return reflection;
}

uint16 Crc_CalculateCRC16ARC(const uint8* Crc_DataPtr, uint32 Crc_Length, uint16 Crc_StartValue16, boolean Crc_IsFirstCall)
{
    // 使用反射后的多项式
    const uint16 Crc_Polynomial = 0xA001; 
    uint16 crcValue = Crc_StartValue16;

    if(Crc_IsFirstCall)
    {
        crcValue = 0xFFFF;
    }

    // 按自然顺序处理每个字节
    for (uint32 i = 0; i < Crc_Length; i++)
    {
        // 反射后的字节直接异或到CRC低字节
        crcValue ^= Reflect(Crc_DataPtr[i], 8);

        for (uint8 bit = 0; bit < 8; bit++)
        {
            // 反射CRC按LSB优先处理,检查最低位
            if (crcValue & 0x0001) 
            {
                crcValue = (crcValue >> 1) ^ Crc_Polynomial;
            }
            else
            {
                crcValue >>= 1;
            }
        }
    }

    // 输出反射后无需额外异或
    return Reflect(crcValue, 16);
}

验证说明

修正后运行测试用例,可得到预期结果:

  • 输入0x00,0x00,0x00,0x00 → 输出0x0000
  • 输入0xF2,0x01,0x83 → 输出0xC2E1
  • 输入0x0F,0xAA,0x00,0x55 → 输出0x0BE3

内容的提问来源于stack exchange,提问作者Flavio Cesar Jimenez Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:47:31