본문 바로가기

개발일지

반도체 SPD EEPROM 데이터 CRC 체크 방법 개발 테스트 (Checksums and Cyclic Redundancy Checks)

728x90

SPD 에서 CRC체크 방식에 대한 JEDEC 설명은 다음과 같습니다.

Newer SPDs use a more robust Cyclic Redundancy Check (CRC) algorithm for validating the contents of the SPD 
EEPROM. The polynomial calculated with this algorithm is x16 + x12 + x5 + 1. The following algorithm is an example of how to code this polynomial.

int Crc16 (char *ptr, int count)
{
	int crc, i;
	crc = 0;
	while (--count >= 0) {
 		crc = crc ^ (int)*ptr++ << 8;
		for (i = 0; i < 8; ++i)
 			if (crc & 0x8000)
 				crc = crc << 1 ^ 0x1021;
			else
 				crc = crc << 1;
 	}
	return (crc & 0xFFFF);
}

char spdBytes[] = { SPD_byte_0, SPD_byte_1, ..., SPD_byte_N-1 };
int data16;
data16 = Crc16 (spdBytes, sizeof(spdBytes));
SPD_byte_126 = (char) (data16 & 0xFF);
SPD_byte_127 = (char) (data16 >> 8);

본인은 자바 개발자라서 일단 자바소스로 CRC체크 하는 테스트 프로그램을 작성해 보도록 합니다.

CRC 체크 부분을 자바소스로 변경하면 아래와 같습니다.

    /**
     * CRC 체크
     *
     * @param dataFrame
     * @param count
     * @return
     */
    public int Crc16(byte[] dataFrame, int count) {
        int crc, i, index = 0;
        crc = 0;
        while (--count >= 0) {
            crc = crc ^ (int) dataFrame[index++] << 8;
            for (i = 0; i < 8; ++i) {
                if ((crc & 0x8000) == 0) {
                    crc = crc << 1;
                } else {
                    crc = crc << 1 ^ 0x1021;
                }
            }
        }
        return (crc & 0xFFFF);
    }

/**
* 00의 예약된 가변 영역의 데이터를 생성하는 메서드 (테스트용)
*
* @param size
* @return
*/
public String getReservedData(int size) {
	String hexData = "";
	for (int index = 0; index < size; index++) {
		hexData += " 00";
	}
	// System.out.println(hexData);
	return hexData;
}

public void makeByteStream(String message) {
    System.out.println(message);
    StringTokenizer token = new StringTokenizer(message, " ");
    int size = token.countTokens();
    System.out.println("size =>  " + size);
    byte dataStream[] = new byte[size];
    byte crcDataStream[] = new byte[2];
    String elementToken;
    byte value = 0;
    int index = 0;

    while (token.hasMoreTokens()) {
    	elementToken = token.nextToken();
    	value = (byte) Integer.parseInt(elementToken, 16);
    	dataStream[index++] = value;
    }

    int crc = Crc16(dataStream, dataStream.length);
    crcDataStream[0] = (byte) (crc & 0x00ff);
    crcDataStream[1] = (byte) (crc >> 8);

	System.out.println(Integer.toHexString(crcDataStream[0]) + " " + Integer.toHexString(crcDataStream[1]));

	System.out.println("CRC LSB =>" + Integer.toString((crcDataStream[0] & 0xff) + 0x100, 16).substring(1).toUpperCase());
    System.out.println("CRC MSB =>" + Integer.toString((crcDataStream[1] & 0xff) + 0x100, 16).substring(1).toUpperCase());
}

public static void main(String[] args) {
    SPD_Test crc = new SPD_Test();
    crc.test1_1();
}  

실행 결과

 

참고로 자바로 구현한 소스도 올립니다. 직접 실행하면서 테스트 해보세요.

SPD_Test.java
0.00MB

728x90