CRC16 校验和:HCS08 与 Kermit 与 XMODEM
我正在尝试将 CRC16 错误检测添加到 Motorola HCS08 微控制器应用程序。但我的校验和不匹配。一个在线 CRC 计算器提供了我在 PC 程序中看到的结果以及我在微博上看到的结果。
它将微处理器的结果称为“XModem”,将 PC 的结果称为“Kermit”。
这两个古老协议指定 CRC16 的使用方式有什么区别?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用相同的基本代码库实现 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
下表显示了它们的不同之处:
其中“反向字节”表示每个字节在处理前进行位反转; ‘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:
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.
我的回忆(我以前经常做调制解调器的事情)是 Kermit 首先使用最低有效位处理数据的每个字节中的位。
大多数软件 CRC 实现(可能是 Xmodem)首先运行数据字节的最高有效位。
查看库源代码时(从 http://www.lammertbies.nl/comm 下载) /software/index.html)用于您链接到的 CRC 计算页面,您将看到 XModem 使用 CRC16-CCITT,其多项式为:
多项式由位图表示(请注意,位 16 它
Kermit 实现使用:
与 XModem 的位图相同,只是相反。
该库附带的文本文件还提到了 Kermit 的以下差异:
因此,修改 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:
The polynomial is represented by the bitmap (note that bit 16 is implied)
The Kermit implementation uses:
which is the same bitmap as XModem's, only reversed.
The text file that accompanies the library also mentions the following difference for Kermit:
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).
X-调制解调器 1K CRC16。
使用输入数据 {0x01, 0x02} 和多项式 0x1021 处理字节 CRC-16
处理第一个输入字节 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。
处理下一个输入字节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
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.
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.
CRC16 XModem 与 CCIT 零相同
CRC16 XModem is the same as CCIT Zero