필자는 원격 측정 스트림을 가지고 있으며이 측정 스트림은 CRC를 각 원격 측정 프레임의 끝에 추가하는 하드웨어 CRC 생성기를 통과합니다. 이제 하드웨어에서 생성 된 CRC를 확인하기 위해 무언가를 만들려고합니다. 올바른 CRC (여러 번 검증 됨)를 계산하는 오래된 레거시 코드 (아래 참조)가 있습니다. 그러나 각 원격 측정 프레임이 300 바이트 이상이고 처리 할 수있는 프레임이 10,000,000 개 이상일 수 있으므로 속도가 느립니다.어떤 CRC Alogrithim입니까? 개선하는 방법?
일부 연구를 통해 나는 표적 접근 방식을 가리키는 몇 가지 문헌을 발견했습니다. 레거시 방법은 Poly of 0x8005를 사용하고 처리하기 전에 각 바이트의 비트 순서를 반대로하고 CRC를 0으로 초기화합니다. 그러나 역전 된 입력과 반대가 아닌 입력을 가진 폴리를위한 테이블을 만들고 단지 첫 번째 바이트의 데이터 (0x10)를 처리하려고하면 레거시 방식이 생성하는 것과 일치하는 것을 얻을 수 없습니다.
calcCRC16 함수 (아래)에서 기존 메서드는 다른 사람이 MSB를 확인하는 것처럼 보이는 LSB를 확인합니다 ... 그리고 내가 본 다른 예제가있는 곳으로 비트 시프트가 있습니다. 왜 비트 순서가이 함수에 전달되기 전에 바뀌 었는지 알기가 어렵습니다. 나는 온라인 계산기를 & 수동으로 8005에서 A001 (역전 된), 정상 및 역 입력 된 바이트, 그리고 내가 생각할 수있는 모든 조합으로 전환하는 테이블에서 조회를하고 있지만 어떤 테이블 접근 방식과도 일치하지는 않는다. 하드웨어 구현시 올바른 것으로 알고있는 레거시 코드
내가 분명한 뭔가를 놓치면 누구든지 나를 도울 수 있습니까? 동일한 출력을 만들기 위해 테이블 기반 접근 방식을 만드는 방법에 대해 어떻게 생각하십니까? 저는 C++의 초심자이며 CRC 생성에 익숙하지 않아 뭔가 근본적인 것을 간과 할 수 있습니다. 하드웨어 CRC에 대해 검증 된 샘플 코드와 출력은 다음과 같습니다
샘플 코드 :
: 난 그냥 열심히 예를 들어
/** ********************************************************************************
* TEST CRC METHOD
*******************************************************************************/
#include <iostream>
using namespace std;
unsigned char swapBits(unsigned char d);
void calcCRC16(unsigned int *CRCVal, unsigned char value);
/** **************************************************************************
* @function main
* TEST CRC METHOd
*******************************************************************************/
int main(int argc, char* argv[])
{
short dataLength = 5;
unsigned int givenCrc;
unsigned int calcCrc;
unsigned char byte[] = {0x10,0xbb,0x42,0x4d,0xfd};
/* Init CRC. */
calcCrc = 0;
cout << "Inital CRC = " << hex << calcCrc << "\n";
/* Read frame data. */
for (int i = 0; i < dataLength; i++)
{
cout << "byte = " << hex << static_cast<int16_t>(byte[i]) << " ";
calcCRC16(&calcCrc, swapBits(byte[i]));
cout << "calcCRC = " << hex << calcCrc << "\n";
}
}
/** ********************************************************************
* @function swapBits
* Swaps the bits so they match the order sent to CRC Gen Hardware
************************************************************************/
unsigned char swapBits(unsigned char d)
{
unsigned char t = 0;
int i = 0;
int n = 0x80;
for(i=0x01; i<0x100; i=i<<1)
{
if (d & i)
{
t|=n;
}
n=n>>1;
}
return t;
}
/** ********************************************************************
* @function calcCRC16
* WORKING METHOD VERIFIED AGAINST CRC HARDWARE
************************************************************************/
void calcCRC16(unsigned int *CRCVal, unsigned char value)
{
unsigned char lsb;
unsigned char bcnt;
for (bcnt=0 ; bcnt<8 ; bcnt++)
{
lsb = (value^*CRCVal) & 0x01;
*CRCVal >>= 1;
value >>= 1;
if (lsb != 0)
{
*CRCVal ^= 0x8005;
}
}
}
출력으로 알고 원격 측정 스트림에서 몇 바이트 코드 Inital CRC = 0
바이트 = 10 calcCRC = b804
바이트 = BB calcCRC = 1fb8
바이트 = 42 = calcCRC 461d
012,351,바이트 = 4D calcCRC = 3d47
바이트 = FD calcCRC = 683e
멋진 작품 마크 – TonyK
감사합니다! 나는 어느 시점에서 A001 테이블을 시도했지만 CRC의 최종 16 비트 반전으로 인해 버려졌습니다. 참고로, 작은 샘플 원격 측정 파일에서 처리 시간이 1 분에서 1.5 초로 단축되었습니다. 다시 한번 감사드립니다. –