arm crc32w有什么作用?

时间:2017-11-09 13:10:41

标签: assembly arm crc arm64

看起来像一个愚蠢的问题,但它返回的值并不是我所期待的...我需要在arm7芯片上模拟crc32w的指令(不支持这个指令),所以我需要交流实现得到相同的结果。我尝试的一切都有所不同。根据{{​​3}}的文档,它应该:

  

CRC32在第一个源操作数中获取输入CRC值,执行a   CRC在第二个源操作数的输入值上,并返回   输出CRC值。第二个源操作数可以是8位,16位或32位。   为了与常用用法对齐,值的位顺序反转为   部分操作,多项式0x04C11DB7用于   CRC计算

这很好,但如果我跑:

uint32_t crc=0xFFFFFFFF; 
uint32_t val=100;
asm volatile("crc32w %w0, %w0, %w1": "+r" (crc): "r" (val)  );

然后我得到了6aff40b7的crc。如果我将相同的数字插入http://www.keil.com/support/man/docs/armclang_asm/armclang_asm_awi1476352818103.htm(或其他在线crc网页),我会得到0x6B9B7A5D。我尝试切换反向位等,但我无法提出6aff40b7。那么,我的问题是crc32w到底是做什么的?

3 个答案:

答案 0 :(得分:2)

在ARM CRC32中使用HAL(硬件抽象层) 设置如下:

/* CRC init function */
void MX_CRC_Init(void)
{
  hcrc.Instance = CRC;
  hcrc.Init.DefaultPolynomialUse =  DEFAULT_POLYNOMIAL_ENABLE;
  hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
  hcrc.Init.InputDataInversionMode =  CRC_INPUTDATA_INVERSION_BYTE; // CRC_INPUTDATA_INVERSION_NONE;
  hcrc.Init.OutputDataInversionMode =  CRC_OUTPUTDATA_INVERSION_ENABLE;  // CRC_OUTPUTDATA_INVERSION_DISABLE;
  hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
  if (HAL_CRC_Init(&hcrc) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}   

我得到的结果与CRC32 / JAMCRC变体一致。 即致电

  const char * ts3 = "123456789";
  MX_CRC_Init();
  crc32 =   HAL_CRC_Calculate(&hcrc, (uint32_t *)ts3, strlen(ts3));

在crc32中给出0x340bc6d9,它对应于CRC-32 / CRCJAM。 它的按位NOT是标准CRC-32。 我不知道为什么叫它JAM

  const char * ts2 = "The quick brown fox jumped over the lazy brown dog";
  MX_CRC_Init();
  crc32 =   HAL_CRC_Calculate(&hcrc, (uint32_t *)ts2, strlen(ts2));

给出0x38dd18f〜= 0xFC722E70

都同意https://crccalc.com/

答案 1 :(得分:2)

// This code assumes that unsigned is at least 4 bytes. If not, use
// unsigned long instead.

// When called with data == NULL, the initial CRC value is returned.
unsigned crc32jamcrc(unsigned crc, void const *mem, size_t len) {
    unsigned char const *data = mem;
    if (data == NULL)
        return 0xffffffff;
    while (len--) {
        crc ^= *data++;
        for (unsigned k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
    }
    return crc;
}

答案 2 :(得分:0)

如果您在stm32中使用CRC32引擎为其提供完整的32位小端字节字,则此C代码将为您提供与在CRC-> DR上删除uint32_t相同的结果。

// This is C code that gives the same results
// as sending words to the STM32 CRC engine.
// Most online calculators apply CRC's to bit reversed
// streams and will therefore, not give the same results.
// Optimally this would be done via DMA in the background.
//
uint32_t stm32_crc32(uint32_t crc, uint32_t data) {

    int i;
    crc = crc ^ data;
    for (i = 0; i < 32; i++) {
        if (crc & 0x80000000)
            crc = ((crc << 1) ^ 0x04C11DB7) ;  
        else
            crc = (crc << 1) & 0xFFFFFFFF;
    }
    return crc;
}