引言
在串行通信幀中,為了保證數(shù)據(jù)在傳輸過程中的完整性,通常采用一種指定的算法對原始數(shù)據(jù)進行計算,得出的一個校驗值。接收方接收到數(shù)據(jù)時,采用同樣的校驗算法對原始數(shù)據(jù)進行計算,若計算結(jié)果和接收到的 校驗值一致 ,說明數(shù)據(jù)校驗正確,該幀數(shù)據(jù)可用,若不一致,說明傳輸過程中出現(xiàn)了差錯,丟棄該幀數(shù)據(jù),請求重發(fā)。常用的校驗算法有奇偶校驗、校驗和、CRC,還有LRC、BCC等不常用的校驗算法。
在諸多檢錯手段中,CRC是最著名的一種。CRC的全稱是循環(huán)冗余校驗,其特點是:檢錯能力強,開銷小,易于用編碼器及檢測電路實現(xiàn)。從其檢錯能力來看,它所不能發(fā)現(xiàn)的錯誤的幾率僅為0.0047%以下。從性能上和開銷上考慮,均遠遠優(yōu)于奇偶校驗及算術(shù)和校驗等方式。因而,在數(shù)據(jù)存儲和數(shù)據(jù)通訊領(lǐng)域,CRC無處不在:著名的通訊協(xié)議X.25的FCS(幀檢錯序列)采用的是CRC-CCITT,WinRAR、NERO、ARJ、LHA等壓縮工具軟件采用的是CRC32,磁盤驅(qū)動器的讀寫采用了CRC16,通用的圖像存儲格式GIF、TIFF等也都用CRC作為檢錯手段。
YTM32B1ME微控制器中提供了硬件的CRC計算引擎,用以加速和簡化用戶程序中的CRC運算。值得注意的是,YTM32B1ME微控制器中還集成了SENT通信外設(shè),SENT通信協(xié)議中也用到了CRC校驗。可以想見,在具體應(yīng)用中,CRC外設(shè)可以配合SENT外設(shè),或者其他在協(xié)議中使用CRC校驗算法的通信過程提供硬件計算引擎的支持。
YTM32的硬件CRC外設(shè)模塊,用戶通過AHB總線向CRC外設(shè)送數(shù)參與計算,然后通過AHB總線送出實時的計算結(jié)果。CRC外設(shè)內(nèi)部實現(xiàn)了CRC4(CRC-ITU)、CRC16(CRC-CCITT)、CRC32(CRC-ethernet)等多項算式的計算引擎,并可配置輸出和輸出數(shù)據(jù)的位交換,通過8b、16b、32b等帶寬方式,向CRC計算引擎送數(shù)。如圖x所示。
圖x CRC外設(shè)系統(tǒng)框圖
原理與機制
CRC算法簡介
CRC的全稱是循環(huán)冗余校驗(Cyclic Redundancy Check),其目的是保證數(shù)據(jù)的完整性,具體應(yīng)用方法,是在發(fā)送數(shù)據(jù)的后面再補充若干位的數(shù)據(jù),使得接收方使用同樣的CRC計算方法,檢查接收到的數(shù)據(jù)的CRC計算結(jié)果是否為0,從而判定接收數(shù)據(jù)的完整性。
CRC的核心算法,就是通過一串“發(fā)送數(shù)據(jù)”,來計算“需要補充的若干數(shù)據(jù)”。CRC的計算過程是用除法求余數(shù)。不同于十進制的除法運算,CRC用的是 2進制的除法運算 ,2進制的除法運算,屬于 模2運算 ,模2運算的特點是: 沒有進位 。
- 模2加法:0+0=0,0+1=1,1+0=1,1+1=0。
- 模2減法:0-0=0,0-1=1,1-0=1,1-1=0。模2加減法實際上就是異或操作,這也是CRC很容易在實際中應(yīng)用的數(shù)學基礎(chǔ)。
- 模2乘法:0x0=0,0x1=0,1x0=0,1x1=1。
- 模2除法:是模2乘法的逆運算,參見下圖示例。
圖x 模2除法
通過除法算式可以形象地想見,當將一串輸入數(shù)據(jù),再在右側(cè)補入N個空位,作為被除數(shù),除以CRC多項式所表示的N位除數(shù)時,若不能除盡,則在除法豎式的最后一個環(huán)節(jié),在最右邊產(chǎn)生一個同補入空位同位寬的余數(shù),那這個余數(shù)就是CRC的計算結(jié)果。此處用一個例子說明CRC的計算過程。如圖x所示。
圖x CRC8計算用例
在這個算例中:
- CRC8的多項式是
x8+x2+x+1
,對應(yīng)的除數(shù)就是二進制數(shù)100000111
- 被除數(shù)是
0x1C
,轉(zhuǎn)化成二進制就是00011100
- CRC8為8位,被除數(shù)后面補8個0,也同時對應(yīng)CRC計算的結(jié)果也是8位
- 最后的計算結(jié)果是
0x54
在CRC解算時,若將CRC計算的結(jié)果換入補充的空位,在進行CRC計算,相當于是將之前CRC計算的余數(shù)同自己相加,根據(jù)CRC計算的加法中0+0=1
和1+1=0
的規(guī)則,剛好可以得到0的計算結(jié)果,從而驗證數(shù)據(jù)在傳輸過程的完整性。
使用在線的計算器,也能算得同樣的結(jié)果。如圖x所示。
圖x 使用在線CRC計算器
細心的讀者可能看到了,這里面還有 初始值 , 結(jié)果異或值 ,輸入數(shù)據(jù)反轉(zhuǎn)和 輸出數(shù)據(jù)反轉(zhuǎn) ,這些名詞都是指什么呢?
- 初始值,是給CRC計算前提供一個初始值(Offset,預(yù)計算值),大部分情況下設(shè)定為0,也可以根據(jù)選定的特定算法指定其他值,有時也被稱為CRC計算的種子(Seed)。結(jié)果異或值,是把計算結(jié)果再異或某一個值。使用初始值和結(jié)果異或值,的目的是防止在某個計算環(huán)節(jié)中,算得全0的中間結(jié)果,導致后續(xù)的CRC余數(shù)一直為0。
- 輸入數(shù)據(jù)反轉(zhuǎn),是指輸入數(shù)據(jù)以字節(jié)為單位按位逆序處理;輸出數(shù)據(jù)反轉(zhuǎn),是指CRC計算結(jié)果整體按位逆序處理;這么做的目的(一個合理的解釋)是右移比左移更容易計算,效率高,它跟大小端無關(guān)。
特別注意,最基本的計算過程大多不需要額外設(shè)定這些參數(shù)(配置成false或者0即可),但有些面向典型應(yīng)用的場景,會對應(yīng)一些特別配置組合(典型配置),產(chǎn)生了不同的算法。如圖x所示。
圖x 多種不同的CRC計算配置
從CRC算法到CRC硬件外設(shè)
示例CRC計算的過程中,使用的是1個8位的數(shù)作為被除數(shù),但實際計算數(shù)據(jù)幀的數(shù)據(jù)大多是一個數(shù)組,這個擴展過程,可以理解為將整個數(shù)據(jù)幀的一串數(shù)據(jù)并排放在一起,當成一個大數(shù)進行計算。實際上,CRC的除法計算,也是一個串行移位的計算過程,可以從左邊算到右邊。在使用CRC硬件外設(shè)進行計算時,對應(yīng)可以逐個向CRC_DATA
寄存器中送數(shù),CRC會使用上次計算結(jié)果和新送入的數(shù)據(jù)位,得到本次計算的結(jié)果,并繼續(xù)參與后續(xù)的計算。CRC硬件外設(shè)的CRC_DATA
寄存器,支持用戶已8位、16位、32位的位寬向CRC計算引擎送數(shù)。
YTM32的硬件CRC支持三種算式:
CRC硬件外設(shè)可以配置初始值(種子,寄存器CRC_INIT
),支持輸入和數(shù)據(jù)的位序反轉(zhuǎn),不支結(jié)果持異或計算,但支持結(jié)果位翻轉(zhuǎn)。通過結(jié)果寄存器CRC_RESULT
可以讀取實時計算的結(jié)果。
需要注意的是,YTM32手冊上列寫的支持CRC多項式的名字,主要還是描述算子,硬件還是使用基本算法執(zhí)行計算。若需要使用某些具體算法配套特定的位序反轉(zhuǎn)、初始值等,還是需要用戶自行配置CRC硬件外設(shè)。
應(yīng)用要點(軟件)
在arm-mcu-sdk
軟件倉庫中,為ytm_crc_0
驅(qū)動設(shè)計的樣例工程crc_basic
中,設(shè)計了計算CRC-16和CRC-32的演示用例。
CRC16 用例
在crc16_test
用例中,實現(xiàn)計算數(shù)列{0x1234, 0x5678, 0x5A5A, 0xA5A5}
的CRC16值,有源碼如下 :
CRC_Init_Type crc16_ccitt =
{
.EnableOutputBitInv = false,
.EnableOutputBitSwap = false,
.EnableInputBitSwap = false,
.CalcMode = CRC_CalcMode_Crc16,
.InitData = 0x0000
};
#define CRC_DATA_LEN 4u
const uint16_t crc16_data_arr[CRC_DATA_LEN] = {0x1234, 0x5678, 0x5A5A, 0xA5A5};
#define CRC16_RESULT 0x4BDCu /* The result CRC calculator with CCITT 32 bits standard. */
void crc16_test(void)
{
/* setup the crc calculator. */
CRC_Init(BOARD_CRC_PORT, &crc16_ccitt);
for (uint32_t i = 0u; i < CRC_DATA_LEN; i++)
{
CRC_SetData16b(BOARD_CRC_PORT, crc16_data_arr[i]);
}
printf("crc16_test ... ");
if (CRC16_RESULT == CRC_GetResult(BOARD_CRC_PORT))
{
printf("succ.");
}
else
{
printf("fail.");
}
printf("rn");
}
使用在線的CRC計算器計算,可以得到相同的計算結(jié)果。如圖x所示。
圖x CRC在線計算器計算CRC16
這里要注意,CRC在線計算器中定義的CRC-16/CCITT
是輸入數(shù)據(jù)反轉(zhuǎn)和輸出數(shù)據(jù)反轉(zhuǎn)的,而樣例代碼中指定的crc16_ccitt
配置參數(shù),實際對應(yīng)CRC在線計算器的CRC-16/XMODEM
計算配置。如果在樣例代碼中,設(shè)定配置參數(shù).EnableOutputBitSwap = true
和.EnableInputBitSwap = true
,也可以得到同CRC在線計算器定義的CRC-16/CCITT
算式相同的計算結(jié)果。
這里顯然對算式的名字存在了誤解。開發(fā)者如果不確定各名字預(yù)設(shè)的配置,也可以使用“自定義”的參數(shù)模型,此時可人為指定各參數(shù)。如圖x所示。
圖x 配置CRC在線計算式使用自定義的參數(shù)模型
CRC32 用例
在crc32_test
用例中,實現(xiàn)計算數(shù)列{0x12345678, 0x56781234, 0x55AA55AA, 0xA5A5A5A5}
的CRC32值,有源碼如下 :
CRC_Init_Type crc32_enet =
{
.EnableOutputBitInv = false,
.EnableOutputBitSwap = false,
.EnableInputBitSwap = false,
.CalcMode = CRC_CalcMode_Crc32,
.InitData = 0xffffffff
};
#define CRC_DATA_LEN 4u
const uint32_t crc32_data_arr[CRC_DATA_LEN] = {0x12345678, 0x56781234, 0x55AA55AA, 0xA5A5A5A5};
#define CRC32_RESULT (0x57738169U) /* The result CRC calculator with CRC-32 standard. */
void crc32_test(void)
{
/* setup the crc calculator. */
CRC_Init(BOARD_CRC_PORT, &crc32_enet);
for (uint32_t i = 0u; i < CRC_DATA_LEN; i++)
{
CRC_SetData(BOARD_CRC_PORT, crc32_data_arr[i]);
}
printf("crc32_test ... ");
if (CRC32_RESULT == CRC_GetResult(BOARD_CRC_PORT))
{
printf("succ.");
}
else
{
printf("fail.");
}
printf("rn");
}
使用在線的CRC計算器計算,可以得到相同的計算結(jié)果。如圖x所示。
圖x CRC在線計算器計算CRC16
總結(jié)
YTM32的CRC硬件外設(shè)模塊能夠執(zhí)行CRC計算,同在線CRC計算器的結(jié)果能夠?qū)?yīng)上。
YTM32的手冊中描述的CRC16-CCITT
和CRC32-ENET
等對CRC計算典型配置的別稱,實際可不必參考。CRC硬件外設(shè)的中CRC計算引擎還是執(zhí)行基本CRC計算,典型配置實際可通過配置相關(guān)計算寄存器位的實現(xiàn),最終可以支持各種各樣的CRC典型算式。
-
微控制器
+關(guān)注
關(guān)注
48文章
7906瀏覽量
153695 -
驅(qū)動器
+關(guān)注
關(guān)注
54文章
8629瀏覽量
149051 -
編碼器
+關(guān)注
關(guān)注
45文章
3775瀏覽量
137140 -
寄存器
+關(guān)注
關(guān)注
31文章
5421瀏覽量
123324 -
CRC校驗
+關(guān)注
關(guān)注
0文章
84瀏覽量
15506
發(fā)布評論請先 登錄
YTM32的LIN通信協(xié)議引擎LinFlexD外設(shè)模塊詳解

PSoC 4 循環(huán)冗余校驗 (CRC)
CRC循環(huán)冗余校驗的算法
如何利用循環(huán)冗余校驗(CRC)計算單元進行傳輸數(shù)據(jù)的校驗呢
循環(huán)冗余校驗碼---CRC碼

crc循環(huán)冗余校驗碼算法

建立循環(huán)冗余校驗CRC校驗數(shù)據(jù)的完整性

Verilog數(shù)字系統(tǒng)基礎(chǔ)設(shè)計中的循環(huán)冗余校驗
CRC循環(huán)冗余校驗簡介

32位可編程循環(huán)冗余校驗(CRC)

評論