搜索到 Arduino CRC32 代码解释

Arduino CRC32 Code Explanation searched

我已经开始使用 Arduino,我给自己设定的下一个任务是了解如何实施 CRC 校验。我想我已经找到了一个不错的代码。但只是实施……不,我想学习。我一般搜索了一些关于 CRC 的信息,我使用了一个 youtube 视频来学习数学基本原理和 another site,它教我如何用 C 语言实现 CRC。尤其是看完之后,脑袋有点超负荷,不过我觉得我明白了其中的原理。

所以,在我希望说服你我想学习这些东西之后,这里是 2nd link,它给出了对我来说太复杂的 Arduino CRC 代码片段。

有几件小事在我脑海中产生问号,例如~0L 是什么意思,或者为什么在 crc-strings 函数的 while 循环中有条件 *s,以及更多的东西。

谁能看一下第 2 个 link 中提供的代码并详细解释它的作用,以便像我这样的普通人也能理解而不只是实现代码?

非常感谢

此致

编辑:我将post根据评论中的要求link与第二个link相关的具体问题。

  1. 在 crc_string 函数中,变量 crc 被初始化为 ~0L。我知道 ~ 是一个位运算符,可以将 0 转换为 1,反之亦然。但是它对 0L 有什么作用呢? 0L到底是什么? NULL 的另一个表达式?为什么要写得这么抽象呢?是否存在更简单的编码方法?

  2. crc_string 函数中的下一行: while(*s) --> *s 在示例中是 "HELLO"。但这是什么意思呢?这不总是真的吗?什么时候可以改成false?我知道一些指针基础知识,但我不明白。

  3. 现在我们深入 while 表达式:crc_update(crc, *s++); --> 在"HELLO"的情况下第二个参数是什么,++在这种情况下做什么?我的意思是,如何将 HELLO 加 1?

我想知道这些之后剩下的就更清楚了,但我可以继续提出更多问题:

  1. 现在我们进入更新功能:我真的不明白整个功能,为什么会有一些0 * 4的移位(这不是没用吗?),这到底是怎么回事行为 pgm_read_dword_near,为什么又发生了一些偏移,为什么在返回 crc 之后,crc 又是 ~?

  2. 在我编辑这个post之前的第一个link中你可以看到作者正在使用table来存储256位的crc。在本教程的此处,有一个包含 16 个条目的 table。我有一个粗略的理解为什么我们使用 tables,我认为作者只使用了 16 个条目,因为 space arduino 提供的有限。但是,尽管如此,这一切在这里是如何运作的?真的没看懂

希望在开始时足够具体。

另一个更一般的 crc 问题:我的意思是,crc 的基本思想是用另一个神秘数字划分一个字节消息,并将剩余部分附加到消息中 --> crc 是剩余部分。但是当我有 2 个字节时我会做什么,例如我想同时传输 "H" 和 "W" 两个字符?那我得crc了。如何将两个 crc 转换为一个最终的 crc?

编辑 2 因为我想回答 James Bowman 的回答:

首先,太棒了,在我提出问题后仅 1 天,代码的所有者就来回答了。

你的指导已经帮了我很多,我试着用第一个字母 "H" 的例子来完成一个循环,直到我卡住了。

我想还会有一些问题出现,如果我现在说废话,希望你也能指正:

2.1。首先,crc 初始化为 0xFFFFFFFF。

2.2。 "HELLO" 就像一个数组。指针在 while 循环中的作用是取消引用该数组的第一个地址,所以它是 "H"

2.3。使用参数调用 crc_update:0xFFFFFFFF 和 "H"。完成后,指针将指向 "E"。

2.4。在更新函数中,tbl_idx 被初始化为 0xFFFFFFFF ^ 0x48("H" 的 ASCII 代码)。那么这里究竟是怎么回事,因为 0x48 只有 1 个字节?我将 0x48 转换为二进制:0100 1000。然后,在按位运算之后,它是:1011 0111。这是正确的吗?所以 tbl_idx 现在是 1011 0111.

2.5。然后pgm搜索功能来了。在文档中,我发现 "dword" 令人困惑: "Read a double word from the program space with a 16-bit (near) address." 但在 table 中,它都是关于 32 位的吗?你能解释一下吗?

2.6。我继续这个功能。因此它在 table 中搜索:1011 0111 & 0x0f,即 0000 0111,然后 ^ 使用 crc>>4(0000 1111 1111 1111 1111 1111 1111 1111 - 正确吗?)这是:好问题......再次不同的字节大小...如果考虑到最右边的字节,则结果将是:1111 1000,因此它会在 table 中查找该值,但只有 16 个条目,而不是 248: (

我想我这里有一个思路错误,无法继续下去。如果你能在这里帮助我,那就太好了。

如果您也有关于 CRC32 的好用且简单的文档,我可能也能理解,请不要犹豫,分享它:-)

我写了你链接到的代码,所以我会尝试回答你的问题。

  1. 使用 ~0L。这是必要的,因为该算法适用于 32 位数字,而 Arduino 的代码默认使用 16 位数字。 "L" 后缀告诉编译器该值为 "long",因此它以 32 位对其进行数学运算。

  2. "s" 的类型是 "pointer to char" - 这通常被认为是 "string" 但在某些情况下它们会有所不同。特别地,“*s”是 s 指向的当前字符。最初 *s 是 H,然后是 E、L、L、O。最后它指向字符串的末尾,因此 *s 为零。此时while循环退出。

  3. 因为"s"是"pointer to char"所以s++表示下一个字符。

  4. Shift with "0*4" 没有任何作用 - 它只是为了显示原始算法中存在的对称性。 pgm_read_dword_near() 是访问数组的获取函数——这是必需的,因为 table 存储在 Arduino 闪存中。最后的反转 (~) 是 CRC-32 算法的一部分。

  5. 事实上,许多 table 大小都是可能的:1 位、2、4 和 8 位很受欢迎。 pycrc 工具允许您生成任何大小的 table。一般来说,table 大小与计算之间存在权衡。这里的代码使用了一个相当小的table,但是每个字节需要做两次查找。