2017-01-26 92 views
1

我正在製作一個程序,它將與引導加載程序進行通信以更新微控制器的固件。除了CRC calculation以外,一切都準備就緒。CRC16-CCITT不正確的結果?

我已經使用來自here的CRC計算函數來計算多項式爲x16 + x12 + x5 + 1(0b10001000000100001)的CRC16。

但輸入0x3304000的結果出來是錯誤的。我檢查了這個website。此外,我有一個python腳本,我複製C複查。 python腳本正確計算了CRC

下面是從網站的代碼:

uint16_t crc16(uint8_t *data_p, unsigned length) 
{ 
    unsigned char i; 
    unsigned int data; 
    unsigned int crc = 0xffff; 

    if (length == 0) 
     return (~crc); 

    do 
    { 
     for (i=0, data=(unsigned int)0xff & *data_p++; 
      i < 8; 
      i++, data >>= 1) 
     { 
       if ((crc & 0x0001)^(data & 0x0001)) 
        crc = (crc >> 1)^POLY; 
       else crc >>= 1; 
     } 
    } while (--length); 

    crc = ~crc; 
    data = crc; 
    crc = (crc << 8) | (data >> 8 & 0xff); 

    return (crc); 
} 
+0

我會責怪排序。 –

+0

我正在傳遞'uint8_t'數組。我認爲endianess不應該是一個問題。 – abhiarora

+0

您如何知道網站正在使用CRC16-CCITT? –

回答

3

我比你貼與你鏈接的網站算法的C代碼,我發現兩個主要區別:

1)您發佈流程以相反的順序位的C代碼的網站。對於CRC計算本身(右移,網站左移)以及處理輸入的每個字節(首先處理最低有效位,網站首先處理最重要位),這都是正確的。

2)C代碼在返回之前將CRC值中的所有位反轉,並且還交換低位和高位字節。該網站的算法不包含這種後期處理。

我已經更新您粘貼相匹配的網站上的C代碼:

uint16_t crc16(const uint8_t *data_p, unsigned length) 
{ 
    unsigned char i; 
    uint8_t data; 
    unsigned int crc = 0; // 0xffff; 

    while (length-- > 0) 
    { 
    for (i = 0, data = *data_p++; 
     i < 8; 
     i++, data <<= 1) 
    { 
     if ((crc >> 15)^(data >> 7)) 
     crc = (crc << 1)^POLY; 
     else 
     crc <<= 1; 

     crc &= 0xffff; 
    } 
    } 

    return crc; 
} 

的差異:

1)data局部變量現在uint8_t類型。

2)crc變量初始化爲0而不是0xFFFF,正如@AShelly所建議的。該網站特別提到它在開始計算之前將所有寄存器初始化爲0。 3)我沒有單獨測試長度0,而是將循環從'do'循環重新編譯爲'while'循環,這樣它就不會首先進入循環,如果'長度'爲0.

4)在for循環中,data向左移動而不是向右移動。這是因爲我們想要先處理它的位,然後是位右邊的位,等等 - 左邊的移位將每個後續位移到高位位置。

5)if語句與輸入的新的比特現在與數據(data >> 7)的高比特比較CRC(crc >> 15)的高比特結合了進位,而不是每一個的低比特。代碼的其餘部分確保crc在第16位沒有位,並且data在第8位不會有位,所以這些位移保證只產生一位。

6)實際的crc計算向左移動而不是右移。

7)將crc向左移位後,我將位置16的任何位屏蔽掉。這是第4點中提到的代碼的一部分,它確保crc >> 15只產生一個位。 (這也可以通過使crcuint16_t類型來完成。)

8)後處理代碼被刪除。最後的crc值將按照循環完成時的原樣返回。

通過這些更改,由C函數生成的CRC與網站相匹配。

+2

很好的答案,但錯過了使用「downto」運算符的機會:'while(length - > 0) – AShelly

+0

感謝您的回答。它按預期工作。我也試圖匹配到該網站已實施的內容,但我想我錯過了幾件事情。很好的答案。值得一百萬贊助人 – abhiarora

1

CRC-16並不是唯一的規範,這取決於初始化和多項式。我懷疑0xFFFF 您使用的網站使用0x0000作爲初始值設定項。

在過去的工作中,我們使用this website來驗證實現,首先驗證了幾個已知輸入的網站結果。

+0

是的,我已經看過他們的算法,並試圖在我的程序中使用0x0000初始值設定項,但它沒有幫助 – abhiarora