[Python] How to calculate CRC for ISO CAN-FD frames

Discussão em 'Python' iniciado por Stack, Fevereiro 19, 2025.

  1. Stack

    Stack Membro Participativo

    I'm working on a study about CRC in ISO CAN-FD but I'm having issues with the calculation of the actual check sequence.

    First of all, I have carefully read the specification ISO 11898-1:2015 that states how the calculation has to be carried out.

    Then, I have defined a frame to try and calculate the CRC on:

    [​IMG]

    Note that the red zeros are stuff-bits.

    The same frame has been added to a CANalzyer configuration, and my CAPL script prints the FrameCRC = 0x6bd.

    I have implemented the algorithm described in the ISO document using Numpy, but my result doesn't match what CANalyzer returns.

    My code is the following (it probably isn't perfect numpy-ic coding, I'm new to this library):

    def crc(data):
    gen_poly = np.array([1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1])
    crc_reg = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

    for bit in data:
    crc_next = abs(bit - crc_reg[0])
    crc_reg = np.roll(crc_reg, -1) # Shift one position left (1)
    crc_reg[-1] = 0 # Shift one position left (2)
    if crc_next == 1:
    reg_new = abs(crc_reg - gen_poly)
    crc_reg = np.copy(reg_new)
    return crc_reg.copy()


    I also thought that maybe I misunderstood the document, and crc_reg and gen_poly have to be 18 bits long. So I modified the code this way:

    • added 18 bits at zero at the end of the frame, instead of 17;
    • gen_poly = np.array([1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1]);
    • crc_reg = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) (18 total bits);

    but it didn't work as well. I really can't figure out where I'm making mistakes. I've reviewed everything many times.

    Edit: as suggested by @Reinderien, I'm providing the input data and the expected output arrays:

    input_data = np.array([
    0, # SOF
    1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, # ID
    0, # RTR
    0, # IDE
    1, # EDL
    0, # RES
    1, # BRS
    0, # ESI
    1, 0, 0, 0, # DLC
    1, 1, 1, 1, 1, 0, 1, 1, 1, # Byte 1
    1, 1, 0, 1, 1, 1, 1, 1, 0, 1, # Byte 2
    1, 1, 1, 1, 0, 1, 1, 1, 1, # Byte 3
    1, 0, 1, 1, 1, 1, 1, 0, 1, 1, # Byte 4
    1, 1, 1, 0, 1, 1, 1, 1, 1, 0, # Byte 5
    1, 1, 1, 1, 1, 0, 1, 1, 1, # Byte 6
    1, 1, 0, 1, 1, 1, 1, 1, 0, 1, # Byte 7
    1, 1, 1, 1, 0, 1, 1, 1, 1, # Byte 8
    1, 1, 0, 0, # StuffCount + Parity
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 # 17 bits at zero
    ])

    expected_output = np.array([0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1]) # 0x6bd

    Continue reading...

Compartilhe esta Página