如何确定 CRC16 初始校验和,以便生成的校验和为零
How to determine CRC16 initial checksum so resulting checksum is zero
正在 SAMD MCU 阵列之间的 SPI 通信总线上工作。
我有一个传入数据包,类似于 { 0x00, 0xFF, 0x00, 0xFF }
。
接收器芯片对传入的数据包执行 CRC16 检查。
因为我每次都期待完全相同的数据包,所以我希望数据包有效时 CRC 校验和为零,而出现传输错误时校验和不为零。
我知道我可以在发送数据包时将计算出的CRC16添加到数据包的末尾,并且在接收端CRC校验将输出0,但在这种情况下不可能将CRC16校验和添加到数据包中因为数据包是由 SPI 线上的多个发送器芯片构建的,并且每个芯片只填充整个数据包中自己的两个字节。
我需要在接收方加载初始 CRC 校验和,因此在检查传入数据包后,生成的 CRC 等于零(如果数据包完好无损)。
答案其实是我要找的,但是是针对CRC32格式的,我其实不懂代码原理,所以无法重写if for CRC16格式。
如有任何帮助,我们将不胜感激!
此致,
妮可
解决方案是简单地使用基于查找 table 的 CRC。如果您不能将校验和(又名 帧校验序列 、FCS)附加到包中,则先执行 table 查找,然后简单地将那个与固定数据的预期顺序。
请注意 "CRC 16" 可能意味着任何东西,有多个版本和(非)标准。最常见的可能是名为 "CRC-16-CCITT" 的算法,它具有 1021h 多边形和初始值 FFFFh,但即使对于那个算法,也有多种算法——有些是正确的,有些是错误的。您最大的挑战将是找到一个值得信赖的 CRC 算法。
但是,我实际上认为 SAMD 专门使用硬件生成的片上 CRC-16-CCITT,用于 DMA 目的。因为这是 SPI,它应该是 DMA-able,所以也许调查一下你是否可以以某种方式使用它。
我找到了解决方案,感谢 Bastian Molkenthin 的建议,他做得很好 online CRC calculator。
他建议尝试对 CRC16 初始值的所有 2^16 值进行蛮力计算。事实上,在几行代码和几微秒后,SAMD51 找到了一个初始值,它与给定缓冲区的零 CRC 值相匹配。
正在 SAMD MCU 阵列之间的 SPI 通信总线上工作。
我有一个传入数据包,类似于 { 0x00, 0xFF, 0x00, 0xFF }
。
接收器芯片对传入的数据包执行 CRC16 检查。
因为我每次都期待完全相同的数据包,所以我希望数据包有效时 CRC 校验和为零,而出现传输错误时校验和不为零。
我知道我可以在发送数据包时将计算出的CRC16添加到数据包的末尾,并且在接收端CRC校验将输出0,但在这种情况下不可能将CRC16校验和添加到数据包中因为数据包是由 SPI 线上的多个发送器芯片构建的,并且每个芯片只填充整个数据包中自己的两个字节。
我需要在接收方加载初始 CRC 校验和,因此在检查传入数据包后,生成的 CRC 等于零(如果数据包完好无损)。
答案
如有任何帮助,我们将不胜感激!
此致, 妮可
解决方案是简单地使用基于查找 table 的 CRC。如果您不能将校验和(又名 帧校验序列 、FCS)附加到包中,则先执行 table 查找,然后简单地将那个与固定数据的预期顺序。
请注意 "CRC 16" 可能意味着任何东西,有多个版本和(非)标准。最常见的可能是名为 "CRC-16-CCITT" 的算法,它具有 1021h 多边形和初始值 FFFFh,但即使对于那个算法,也有多种算法——有些是正确的,有些是错误的。您最大的挑战将是找到一个值得信赖的 CRC 算法。
但是,我实际上认为 SAMD 专门使用硬件生成的片上 CRC-16-CCITT,用于 DMA 目的。因为这是 SPI,它应该是 DMA-able,所以也许调查一下你是否可以以某种方式使用它。
我找到了解决方案,感谢 Bastian Molkenthin 的建议,他做得很好 online CRC calculator。
他建议尝试对 CRC16 初始值的所有 2^16 值进行蛮力计算。事实上,在几行代码和几微秒后,SAMD51 找到了一个初始值,它与给定缓冲区的零 CRC 值相匹配。