匹配STM32F0和zlib中的CRC32 [英] Matching CRC32 from STM32F0 and zlib

查看:381
本文介绍了匹配STM32F0和zlib中的CRC32的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行Linux和STM32F0的计算机之间建立通信链接.我想对我的数据包使用某种类型的错误检测,并且由于STM32F0具有CRC32 hw,并且我在Linux上具有带有CRC32的zlib,所以我认为对我的项目使用CRC32是一个好主意.问题在于,在不同平台上,对于相同数据,我不会获得相同的CRC值.

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 and I have zlib with CRC32 on Linux I thought it would be a good idea to use CRC32 for my project. The problem is that I won't get the same CRC value for the same data on the different platforms.

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>

int
main(void)
{
  uint8_t byte0 = 0x00;
  uint32_t crc0 = crc32(0L, Z_NULL, 0);
  crc0 = crc32(crc0, &byte0, 1);
  printf("CRC32 value of %" PRIu8 " is: %08" PRIx32 "\n", byte0, crc0);
}

输出CRC32 value of 0 is: d202ef8d,该值与多个在线计算器上的结果相匹配.

outputs CRC32 value of 0 is: d202ef8d which matches the result on several online calculators.

尽管我在STM32上使用的任何设置似乎都无法获得相同的CRC. 我发现了有关CRC硬件如何计算其值的流程图

It seems though that whatever settings I use on the STM32 I can't get the same CRC. I have found a flowchart on how the CRC hw calculates its value in an application note from ST but I can't figure out how it's done in zlib.

有人知道他们是否兼容吗?

Does anyone know if they are compatible?

[edit 1]它们都使用相同的init值和多项式.

[edit 1] They both uses the same init value and polynomial.

[edit 2]由于STM32代码使用的是硬件,因此相对而言是不间断的.

[edit 2] The STM32 code is relatively uninteresging since it's using the hw.

...
/* Default values are used for init value and polynomial, see edit 1 */
CRC->CR |= CRC_CR_RESET;
CRC->DR = (uint8_t)0x00;
uint32_t crc = CRC->DR;
...

推荐答案

从文档中可以看出,您的STM32代码不仅不有趣,而且还很不完整.从文档中,为了使用CRC硬件,您需要:

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. 通过RCC外设启用CRC外设时钟.
  2. 通过配置初始CRC值寄存器(CRC_INIT),将CRC数据寄存器设置为初始CRC值.(a)
  3. 分别通过CRC控制寄存器(CRC_CR)中的REV_IN [1:0]和REV_OUT位设置I/O反向位顺序.(a)
  4. 通过CRC中的POLYSIZE [1:0]位设置多项式大小和系数 控制寄存器(CRC_CR)和CRC多项式寄存器(CRC_POL).(b)
  5. 通过CRC控制寄存器(CRC_CR)中的复位位复位CRC外设.
  6. 将数据设置到CRC数据寄存器.
  7. 读取CRC数据寄存器的内容.
  8. 禁用CRC外设时钟.
  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.

特别注意步骤2、3和4,它们定义了要计算的CRC.他们说他们的示例的rev_in和rev_out为false,但是对于zlib crc,它们必须为true.根据硬件的实现方式,多项式也可能需要颠倒(0xedb88320UL).初始CRC必须为0xffffffff,最终CRC取反以匹配zlib crc.

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.

这篇关于匹配STM32F0和zlib中的CRC32的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆