본문 바로가기
HardWare

MODBUS 개요

by Taesung 2025. 9. 29.
728x90

<!doctype html>

CRC 계산과 해석

— Lammert Bies의 “On-line CRC calculation and free library”를 참고하여 정리한 실무 가이드

1) CRC(순환중복검사)란?

CRC(Cyclic Redundancy Check)는 전송 또는 저장 중에 발생할 수 있는 비트 오류를 검출하기 위해 전송 데이터에 대해 다항식 기반의 나머지를 붙이는 방법입니다. CRC는 하드웨어·소프트웨어에서 효율적으로 구현 가능하며 짧은 버스트 오류나 단일/다중 비트 오류 검출에 매우 효과적입니다. :contentReference[oaicite:1]{index=1}

2) CRC의 수학적 배경(간단히)

메시지 비트열을 하나의 다항식으로 보고, 미리 정한 생성 다항식 G(x)로 나눈 나머지를 CRC로 사용합니다. 연산은 모듈로-2(=비트 단위 XOR, 캐리 무시)로 이루어지므로 하드웨어 구현이 간단합니다. :contentReference[oaicite:2]{index=2}

실무: 다항식(예: CRC-16: 0x8005, CRC-CCITT: 0x1021 등)과 초기값(init), 반사(reflect in/out), 최종 XOR(xorout) 같은 파라미터가 서로 다른 구현 간의 결과 차이를 만듭니다. 구현 시 이 파라미터들을 정확히 맞춰야 호환됩니다. :contentReference[oaicite:3]{index=3}

3) 자주 쓰이는 CRC 다항식(참조)

이름 다항식 (hex) 특징 / 용도
CRC-16 0x8005 (반사 표현 0xA001) Modbus RTU 등에서 널리 사용
CRC-CCITT (CRC-16-CCITT) 0x1021 통신 규격, 표준 테스트 문자열(“123456789”) 검증에 자주 사용
CRC-32 0x04C11DB7 네트워크 패킷, 파일 무결성

출처: Lammert Bies — 다항식 및 이론적 설명. :contentReference[oaicite:4]{index=4}

4) Modbus CRC-16(실무 파라미터)

  • 다항식: 0x8005 (반사형으로 0xA001로 구현되는 경우가 일반적)
  • 초기값(init): 0xFFFF
  • 반사(in/out): 적용(일반적으로 true)
  • 최종 XOR: 0x0000
  • 바이트 전송 순서: LSB(하위 바이트) 먼저 전송

(위 파라미터 표준은 Lammert Bies 설명과 업계 관행을 기반으로 요약했습니다). :contentReference[oaicite:5]{index=5}

5) 구현 방법 — 비트 연산(단순) vs 테이블(빠름)

비트 단위(루프) 구현 — 이해하기 쉬움

// C: Modbus-style CRC-16 (bitwise)
#include <stdint.h>
uint16_t crc16_bitwise(const uint8_t *buf, size_t len) {
  uint16_t crc = 0xFFFF;
  for (size_t i = 0; i < len; ++i) {
    crc ^= buf[i];
    for (int j = 0; j < 8; ++j) {
      if (crc & 0x0001) crc = (crc >> 1) ^ 0xA001;
      else crc >>= 1;
    }
  }
  return crc; // 반환값: 0xHHLL (High<<8 | Low), 전송 시 LSB 먼저
}

테이블 기반(lookup) — 속도 우선

256-entry 테이블을 사용하면 바이트 단위로 빠르게 갱신할 수 있어 실무에서는 보통 이 방법을 사용합니다. 테이블은 런타임에 생성하거나 정적 테이블로 코드에 포함시킵니다(임베디드에선 정적 테이블 선호).

// C: 테이블 방식 (사용 예)
uint16_t crc = 0xFFFF;
for (size_t i=0; i<len; ++i) {
  uint8_t idx = (uint8_t)(crc ^ buf[i]);
  crc = (crc >> 8) ^ crc16_table[idx];
}

6) 검증(테스트 벡터)

구현 검증을 위해 널리 쓰이는 테스트 문자열은 "123456789" 입니다. CRC 계산기가 표준과 일치한다면 이 문자열에 대해 알려진 결과와 일치해야 합니다(이 방법은 Lammert Bies 페이지에서 권장됨). :contentReference[oaicite:6]{index=6}

표현 데이터 예상 CRC
CRC-16-IBM (예) 123456789 0xBB3D (구현에 따라 다름—파라미터에 유의)

테스트 벡터는 사용된 CRC 파라미터(init/reflect/xorout)에 따라 값이 달라집니다. 동일 파라미터를 사용했는지 확인하세요.

7) Python 예제

# Python: simple Modbus CRC
def modbus_crc(data: bytes) -> int:
    crc = 0xFFFF
    for b in data:
        crc ^= b
        for _ in range(8):
            if crc & 0x0001:
                crc = (crc >> 1) ^ 0xA001
            else:
                crc >>= 1
    return crc

frame = bytes([0x01,0x03,0x00,0x6B,0x00,0x03])
print(hex(modbus_crc(frame)))  # 예: 0x7687

8) 구현 시 주의사항 (체크리스트)

  • 파라미터 확인: 다항식, 초기값, 반사, xorout을 정확히 맞출 것 — 구현간 불일치의 가장 흔한 원인.
  • 바이트 순서(Endianness): Modbus는 CRC를 LSB 먼저 전송. 전송-수신 순서 일치 필요.
  • 프레임 경계: RTU처럼 프레임 경계가 명확하지 않을 경우 CRC 처리 범위를 정확히 지정해야 함.
  • 테스트 벡터: “123456789” 또는 공개된 바이트 벡터로 검증.
  • 성능: 임베디드에서 빈번한 계산은 테이블 방식이나 하드웨어 가속 검토.

Lammert Bies의 문서는 CRC 이론·선택권고·테스트 방법을 상세히 설명하고 있습니다. 구현 전 해당 문서를 참고해 파라미터를 정확히 이해하세요. :contentReference[oaicite:7]{index=7}

9) 추가 리소스

CRC 계산과 해석 — Lammert Bies 참조 (Modbus/CRC-16 중심)

CRC 계산과 해석

— Lammert Bies의 “On-line CRC calculation and free library”를 참고하여 정리한 실무 가이드

1) CRC(순환중복검사)란?

CRC(Cyclic Redundancy Check)는 ...

```

9) 추가 리소스

10) Modbus CRC16 계산기



작성일: 2025-09-29 · 본 문서는 Lammert Bies의 공개 자료를 참고·요약하여 작성했습니다.
```