Matching CRC32 from STM32F0 and zlib

后端 未结 5 1043
隐瞒了意图╮
隐瞒了意图╮ 2021-02-10 17:53

I\'m working on a communication link between a computer running Linux and a STM32F0. I want to use some kind of error detection for my packets and since the STM32F0 has CRC32 hw

相关标签:
5条回答
  • 2021-02-10 18:10

    The CRC32 implementation on STM32Fx seems to be not the standard CRC32 implementation you find on many online CRC calculators and the one used in zip.

    STM32 implements CRC32-MPEG2 which uses big endian and no final flip mask compared to the zip CRC32 which uses little endian and a final flip mask.

    I found this online calculator which supports CRC32-MPEG2.

    If you are more interested on other CRC algorithms and their implementation, look at this link.

    PS: The HAL driver from STM supports input in byte, half word and word formats and they seem to work fine for STM32F0x in v1.3.1

    0 讨论(0)
  • 2021-02-10 18:12

    From my experience, you can not compare the CRC32 code between the STM32 CRC unit output with the online CRC32 calculator.

    Please find my CRC32 calculator for STM32 in this link.

    This function has been used in my project, and proved to be correct.

    0 讨论(0)
  • 2021-02-10 18:19

    I had similar issues implementing a CRC on an STM32 CRC module where the final checksum was not matching. I was able to fix this by looking at the example code in stm32f30x_crc.c that is provided with STMCube. In the source it has a function for 8-bit CRC that used the following code

    (uint8_t)(CRC_BASE) = (uint8_t) CRC_Data;

    to write to the DR register. As stated previously, the line CRC->DR is defined as volatile uint32_t which will access the whole register. It would have been helpful if ST had been more explicit about accessing the DR register rather than simply saying it supports 8-bit types.

    0 讨论(0)
  • 2021-02-10 18:21

    From the documentation, it appears that your STM32 code is not just uninteresting — it is rather incomplete. From the documentation, in order to use the CRC hardware you need to:

    1. Enable the CRC peripheral clock via the RCC peripheral.
    2. Set the CRC Data Register to the initial CRC value by configuring the Initial CRC value register (CRC_INIT).(a)
    3. Set the I/O reverse bit order through the REV_IN[1:0] and REV_OUT bits respectively in CRC Control register (CRC_CR).(a)
    4. Set the polynomial size and coefficients through the POLYSIZE[1:0] bits in CRC Control register (CRC_CR) and CRC Polynomial register (CRC_POL) respectively.(b)
    5. Reset the CRC peripheral through the Reset bit in CRC Control register (CRC_CR).
    6. Set the data to the CRC Data register.
    7. Read the content of the CRC Data register.
    8. Disable the CRC peripheral clock.

    Note in particular steps 2, 3, and 4, which define the CRC being computed. They say that their example has rev_in and rev_out false, but for the zlib crc, they need to be true. Depending on the way the hardware is implemented, the polynomial will likely need to reversed as well (0xedb88320UL). The initial CRC needs to be 0xffffffff, and the final CRC inverted to match the zlib crc.

    0 讨论(0)
  • 2021-02-10 18:22

    I haven't tested this, but I suspect that you're not, in fact, doing an 8-bit write on the STM32.

    Instead you're probably doing a write to the full width of the register (32 bits), which of course means you're computing the CRC32 of more bytes than you intended.

    Disassemble the generated code to analyze the exact store instruction that is being used.

    0 讨论(0)
提交回复
热议问题