CRC字节序转换

4

我正在使用一块带有硬件CRC计算单元的ARM Cortex M3开发板。它支持3种标准CRC多项式。该模块的接口非常简单。我需要提供指向数据和数据长度的指针。我的问题是它按照LSB(最低位优先)计算。而我需要知道CRC Msb first(xmodem crc16-itt)。有没有办法将它得到的计算结果转换为Msb first?


4
你说的“计算从最低有效位(LSB)开始”,LSB是指最不重要的位还是最不重要的字节?你的问题是比特顺序还是字节顺序?我猜测你并不是仅仅说结果包含正确的2字节CRC,只是顺序颠倒了吧? - TJD
这是什么Cortex M3开发板/芯片? - old_timer
sam3s4是您所说的。现在是关于速度还是尺寸?您是否必须使用硬件crc引擎,或者如果您有一个小型软件解决方案呢? - old_timer
为什么数据以错误的字节序存储?是因为传输、复制或共享的方式不能像接收/发送一样进行交换吗? - old_timer
@dwelch:在创建固件时,您需要在PC上创建一个文件,该文件的字节序与ARM不同。当文件传输到设备时,它会保存在闪存中。由于我正在传输固件,因此无法切换字节顺序。 - stdcall
在PC上,您可以使用不同的字节序计算CRC,并且不像在ARM上那样产生太多成本。这是速度问题还是大小问题?有关小尺寸软件解决方案怎么样?或者是更大的足迹但更快的软件解决方案呢? - old_timer
3个回答

2

编辑/改写:

根据提供的信息,我认为您有以下几个选择:

1)在主机上排列数据(假设主机不像微控制器那样受资源限制),以便微控制器的工作量较少。

2)使用可能使其更快的特性/指令制作(字节交换)数据的副本,然后让硬件CRC引擎计算CRC。

3)不使用硬件CRC引擎,使用软件计算CRC。

4)忽略CRC。

5)使用不同的微控制器(可以处理此用例)。


这是Atmel sam3s4芯片。我查看了数据手册,没有提到有关交换字节序的内容。 - stdcall

0
[...] 我需要知道CRC Msb先(xmodem crc16-itt)。有没有办法将它得到的计算结果转换为Msb先?
xmodem crc16-itt对字节数据进行操作。因此,最高有效字节或最低有效字节仅影响CRC值的表示方式。只需交换计算出的值即可 - 例如使用__REV16() CMSIS函数。
编辑:
我假设双方都将0x01 0x02 0x03 0x04视为这样。如果一方在内存中看到不同的字节,例如0x04 0x03 0x02 0x01,则CRC将失败。但您可能希望尽早修复它,因为在处理数据时,这将使您头痛不已。

这个不行,两端计算方式必须相同才能得到相同的结果0x6909 != 0xBB96 != C52D。在滚动原始CRC时,字节交换不会产生干净的CRC 0x6959 != 0x0000等。 - old_timer
crc 是一种基于比特序列的串行计算,通过改变比特顺序,你期望获得相同的结果吗?基本上,如果我拿20个零和20个一,所有串行序列的组合是否都会产生相同的 crc? - old_timer
我说的是字节顺序,不是顺序。当使用单个字节时,字节顺序不适用。当然,顺序始终很重要。 - Turbo J
2
所涉及的硬件会占用一块内存并按照某种顺序读取它,但是字节的顺序被放置在相反的顺序中,因此字节将按不同的顺序进行评估。问题是,在不必复制交换字节数据的情况下(在将其提供给硬件之前),该怎么办。到目前为止,我除了不使用硬件外,还想不出其他解决方案。使用软件很容易,但可能比硬件解决方案慢,只有测试才能确定软件是否比交换和使用硬件更快。 - old_timer
如果发送方评估并发送字符串“12345678”,而另一端评估“21436587”或“43218765”,则CRC不通过。现在,为什么另一端以这种方式接收数据是一个好问题,也许解决方案就在这里。 - old_timer

-1

只需像这样交换2个字节:

unsigned short crc_little_endian = ...; // call to your CRC function
unsigned short crc_big_endian = (crc_little_endian >> 8) | (crc_little_endian << 8);

有超过两个字节,它是128个字节。逐个翻转所有字节并不高效。 - stdcall
API是否支持逐个字节输入?如果是,请按相反的顺序输入。如果不支持,则需要自己反转顺序。或者,在软件中进行计算。有很多快速算法可用,特别是那些具有256字节预计算值表的算法。 - Pat
不,它不是。而且目前的实现是预先计算的。但你知道嵌入式硬件,我需要将空间保存到更重要的东西,比如代码... - stdcall
这个不行,两端计算方式必须相同才能得到相同的结果0x6909 != 0xBB96 != C52D。在滚动原始CRC时,字节交换不会产生干净的CRC 0x6959 != 0x0000等。 - old_timer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接