CRC16 校验和:HCS08 与 Kermit 与 XMODEM

发布于 2024-10-07 15:46:31 字数 276 浏览 8 评论 0 原文

我正在尝试将 CRC16 错误检测添加到 Motorola HCS08 微控制器应用程序。但我的校验和不匹配。一个在线 CRC 计算器提供了我在 PC 程序中看到的结果以及我在微博上看到的结果。

它将微处理器的结果称为“XModem”,将 PC 的结果称为“Kermit”。

这两个古老协议指定 CRC16 的使用方式有什么区别?

I'm trying to add CRC16 error detection to a Motorola HCS08 microcontroller application. My checksums don't match, though. One online CRC calculator provides both the result I see in my PC program and the result I see on the micro.

It calls the micro's result "XModem" and the PC's result "Kermit."

What is the difference between the way those two ancient protocols specify the use of CRC16?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

_蜘蛛 2024-10-14 15:46:31

您可以使用相同的基本代码库实现 16 位 IBM、CCITT、XModem、Kermit 和 CCITT 1D0F。请参阅使用代码的 http://www.acooke.org/cute/16bitCRCAl0.html来自 http://www.barrgroup.com/Embedded- Systems/How-To/CRC-Calculation-C-Code

下表显示了它们的不同之处:

name    polynomial  initial val  reverse byte?  reverse result?  swap result?
CCITT         1021         ffff             no               no            no
XModem        1021         0000             no               no            no
Kermit        1021         0000            yes              yes           yes
CCITT 1D0F    1021         1d0f             no               no            no
IBM           8005         0000            yes              yes            no

其中“反向字节”表示每个字节在处理前进行位反转; ‘reverse result’表示将16位结果处理后进行位反转; ‘swap result’表示处理后结果中的两个字节被交换。

以上所有内容均通过测试向量针对 http://www.lammertbies.nl/ 进行了验证comm/info/crc-calculation.html(如果这是错误的,我们都迷路了......)。

因此,在您的特定情况下,您可以通过对每个字节进行位反转、对最终结果进行位反转,然后交换结果中的两个字节,将 XModem 的代码转换为 Kermit。

[我相信,但尚未检查或计算出细节,反转每个字节相当于反转多项式(加上一些额外的细节)。这就是为什么你会在不同的地方看到对于基本相同的算法有非常不同的解释。

另外,上述方法效率不高,但适合测试。如果你想要高效,最好的办法就是将上面的内容转换为查找表。]

编辑我上面所说的 CCITT 记录在 RevEng 目录 为 CCITT-FALSE。有关更多信息,请参阅上面链接中我的博客文章的更新。

you can implement 16 bit IBM, CCITT, XModem, Kermit, and CCITT 1D0F using the same basic code base. see http://www.acooke.org/cute/16bitCRCAl0.html which uses code from http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code

the following table shows how they differ:

name    polynomial  initial val  reverse byte?  reverse result?  swap result?
CCITT         1021         ffff             no               no            no
XModem        1021         0000             no               no            no
Kermit        1021         0000            yes              yes           yes
CCITT 1D0F    1021         1d0f             no               no            no
IBM           8005         0000            yes              yes            no

where 'reverse byte' means that each byte is bit-reversed before processing; 'reverse result' means that the 16 bit result is bit-reversed after processing; 'swap result' means that the two bytes in the result are swapped after processing.

all the above was validated with test vectors against http://www.lammertbies.nl/comm/info/crc-calculation.html (if that is wrong, we are all lost...).

so, in your particular case, you can convert code for XModem to Kermit by bit-reversing each byte, bit reversing the final result, and then swapping the two bytes in the result.

[i believe, but haven't checked or worked out the details, that reversing each byte is equivalent to reversing the polynomial (plus some extra details). which is why you'll see very different explanations in different places for what is basically the same algorithm.

also, the approach above is not efficient, but is good for testing. if you want efficient the best thing to do is translate the above to lookup-tables.]

edit what i have called CCITT above is documented in the RevEng catalogue as CCITT-FALSE. for more info, see the update to my blog post at the link above.

拥抱我好吗 2024-10-14 15:46:31

我的回忆(我以前经常做调制解调器的事情)是 Kermit 首先使用最低有效位处理数据的每个字节中的位。

大多数软件 CRC 实现(可能是 Xmodem)首先运行数据字节的最高有效位。

查看库源代码时(从 http://www.lammertbies.nl/comm 下载) /software/index.html)用于您链接到的 CRC 计算页面,您将看到 XModem 使用 CRC16-CCITT,其多项式为:

x^16 + x^12 + x^5 + 1  /* the '^' character here represents exponentition, not xor */

多项式由位图表示(请注意,位 16 它

0x1021 == 0001 0000 0010 0001  binary

Kermit 实现使用:

0x8408 == 1000 0100 0000 1000  binary

与 XModem 的位图相同,只是相反。

该库附带的文本文件还提到了 Kermit 的以下差异:

仅适用于 CRC-Kermit 和 CRC-SICK:在所有输入处理之后,计算 CRC 的补码并交换 CRC 的两个字节。

因此,修改 CRC 例程以匹配 PC 结果应该很容易。请注意,CRC 库中的源代码似乎具有相当自由的许可证 - 或多或少按原样使用它可能是有意义的(至少是适用于您的应用程序的部分)。

My recollection (I used to do modem stuff way back when) is that Kermit processes the bits in each byte of the data using the least significant bit first.

Most software CRC implementations (Xmodem, probably) run through the data bytes most significant bit first.

When looking at the library source (download it from http://www.lammertbies.nl/comm/software/index.html) used for the CRC Calculation page you linked to, you'll see that XModem uses CRC16-CCITT, the polynomial for which is:

x^16 + x^12 + x^5 + 1  /* the '^' character here represents exponentition, not xor */

The polynomial is represented by the bitmap (note that bit 16 is implied)

0x1021 == 0001 0000 0010 0001  binary

The Kermit implementation uses:

0x8408 == 1000 0100 0000 1000  binary

which is the same bitmap as XModem's, only reversed.

The text file that accompanies the library also mentions the following difference for Kermit:

Only for CRC-Kermit and CRC-SICK: After all input processing, the one's complement of the CRC is calculated and the two bytes of the CRC are swapped.

So it should probably be easy to modify your CRC routine to match the PC result. Note that the source in the CRC library seems to have a pretty liberal license - it might make sense to use it more or less as is (at least the portions that apply for your application).

随遇而安 2024-10-14 15:46:31

X-调制解调器 1K CRC16。

使用输入数据 {0x01, 0x02} 和多项式 0x1021 处理字节 CRC-16

  1. Init crc = 0
  2. 处理第一个输入字节 0x01:
    2.1 将第一个输入字节 0x01 '异或入' 到 crc 的 MSB(!) 中:
    0000 0000 0000 0000(CRC)
    0000 0001 0000 0000(输入字节0x01左移8)

    <小时>

    0000 0001 0000 0000 = 0x0100
    该结果的 MSB 是我们当前的被除数:MSB(0x100) = 0x01。
    2.2 所以 0x01 是被除数。从我们的表中获取除法的余数:crctable16[0x01] = 0x1021。 (这个值是通过上面的手动计算得出的。)
    请记住当前的 crc 值为 0x0000。移出当前 crc 的 MSB 并与当前余数进行异或以获得新的 CRC:
    0001 0000 0010 0001 (0x1021)
    0000 0000 0000 0000(CRC 0x0000 左移 8 = 0x0000)

    <小时>

    0001 0000 0010 0001 = 0x1021 = 中间 crc。

  3. 处理下一个输入字节0x02:
    目前我们有中间 crc = 0x1021 = 0001 0000 0010 0001。
    3.1 将输入字节 0x02 '异或入' 到 crc 的 MSB(!) 中:
    0001 0000 0010 0001(CRC 0x1021)
    0000 0010 0000 0000(输入字节0x02左移8)

    <小时>

    0001 0010 0010 0001 = 0x1221
    该结果的 MSB 是我们当前的被除数:MSB(0x1221) = 0x12。
    3.2 所以0x12是被除数。从我们的表中获取除法的余数:crctable16[0x12] = 0x3273。
    请记住当前的 crc 值为 0x1021。移出当前 crc 的 MSB 并与当前余数进行异或以获得新的 CRC:
    0011 0010 0111 0011 (0x3273)
    0010 0001 0000 0000(CRC 0x1021 左移 8 = 0x2100)

    <小时>

    0001 0011 0111 0011 = 0x1373 = 最终 crc。

X-Modem 1K CRC16.

Process for bytewise CRC-16 using input data {0x01, 0x02} and polynomial 0x1021

  1. Init crc = 0
  2. Handle first input byte 0x01:
    2.1 'Xor-in' first input byte 0x01 into MSB(!) of crc:
    0000 0000 0000 0000 (crc)
    0000 0001 0000 0000 (input byte 0x01 left-shifted by 8)


    0000 0001 0000 0000 = 0x0100
    The MSB of this result is our current divident: MSB(0x100) = 0x01.
    2.2 So 0x01 is the divident. Get the remainder for divident from our table: crctable16[0x01] = 0x1021. (Well this value is famila from the manual computation above.)
    Remember the current crc value is 0x0000. Shift out the MSB of current crc and xor it with the current remainder to get the new CRC:
    0001 0000 0010 0001 (0x1021)
    0000 0000 0000 0000 (CRC 0x0000 left-shifted by 8 = 0x0000)


    0001 0000 0010 0001 = 0x1021 = intermediate crc.

  3. Handle next input byte 0x02:
    Currently we have intermediate crc = 0x1021 = 0001 0000 0010 0001.
    3.1 'Xor-in' input byte 0x02 into MSB(!) of crc:
    0001 0000 0010 0001 (crc 0x1021)
    0000 0010 0000 0000 (input byte 0x02 left-shifted by 8)


    0001 0010 0010 0001 = 0x1221
    The MSB of this result is our current divident: MSB(0x1221) = 0x12.
    3.2 So 0x12 is the divident. Get the remainder for divident from our table: crctable16[0x12] = 0x3273.
    Remember the current crc value is 0x1021. Shift out the MSB of current crc and xor it with the current remainder to get the new CRC:
    0011 0010 0111 0011 (0x3273)
    0010 0001 0000 0000 (CRC 0x1021 left-shifted by 8 = 0x2100)


    0001 0011 0111 0011 = 0x1373 = final crc.

昔日梦未散 2024-10-14 15:46:31

CRC16 XModem 与 CCIT 零相同

CRC16 XModem is the same as CCIT Zero

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文