Search
🥫

CAN 통신의 개념과 원리

CAN 통신이란?

Controller Area Network의 약자로, 1980년대 Bosch사에 의해 개발된 메시지 기반 네트워크 프로토콜로, 차량 내 장치들이 서로 통신하기 위해 설계되었다.
호스트 컴퓨터 없이 마이크로 컨트롤러나 장치들이 서로 통신할 수 있는 것이 특징이다. 호스트 컴퓨터가 존재할 수도 있다.
차량 내 ECU(Electronic control unit)들은 CAN 프로토콜을 사용하여 통신한다.
최근에는 차량 뿐만 아니라 산업화용 자동화기기나 의료용 장비에도 사용되고 있다.
기존에는 각 장치들 간 통신을 위해 직접 전선을 1:1 연결해야 했기 때문에 장치가 늘어날수록 전선 수가 급격히 늘어나 차량의 무게가 증가하고 비용이 증가하였다. 이를 해결하기 위해 하나의 전선(BUS)을 두고 각 장치들을 버스에만 연결하는 방식을 고안한 것인데, 이것이 CAN BUS이다.
장치들은 상기 CAN BUS에 broadcast하는 방식으로 통신하는데, 충돌이 발생할 경우 식별자(ID)에 따라 우선순위가 높은 쪽이 우선권을 갖는다.

OSI 모델

CAN 통신은 OSI 모델에서 1, 2, 4계층이 정의되어 있다.

Transport 계층

데이터 전송 오류가 났을 때 재전송을 하는 부분만 정의되어 있다.

Data link 계층

logical link control (LLC) 계층과 medium access control (MAC) 계층으로 이루어져 있다.
전기적 신호를 데이터 프레임으로 전환하고, 데이터 충돌을 중재하고, 데이터 전송 시 acknowledgment 응답을 하거나, 에러 감지 및 알림 등을 보내는 것을 정의하고 있다.

Physical 계층

비트 타이밍, 트랜시버와 버스의 특성 등 물리적인 스펙을 정의하고 있다. 단, 케이블이나 커넥터는 정의하고 있지 않다.
high-speed CAN (ISO 11898)과 low-speed CAN (ISO 11519) 두 가지가 정의되어 있다.
High speed CAN (ISO11898-2)
40Kbps ~ 1Mbps의 전송속도를 지원한다.
가장 일반적으로 사용되며, DeviceNet, CANopen 프로토콜에 사용되는 물리적 표준이다.
CAN 버스 양 끝에 120 ohm 종단 저항을 사용한다.
Low Speed CAN (ISO11898-3)
40Kbps ~ 125Kbps 전송속도를 지원한다.
CAN 버스 라인 중 하나가 단선되어도 정상적으로 통신을 계속 할 수 있어 Fault Tolerant CAN 이라고도 부른다.
각 장비마다 트랜시버에 종단저항을 설치해야 한다.

CAN BUS 구성

CAN 통신을 위해서는 CAN 리시버 및 CAN 트랜시버가 필요하다.
MCU에 CAN 컨트롤러가 내장된 경우 별도의 CAN 리시버만 부착하면 된다.

통신 방식

하나의 버스(전선) 상에서 여러 장치가 동시에 통신하기 때문에 메시지의 충돌이 발생한다. 이를 해결하기 위해 도입한 것이 우성(dominant) 비트와 열성(recessive) 비트 개념이다.
CAN 버스는 CAN High와 CAN Low 두 가닥의 전선으로 이루어져 있다.
CAN 리시버는 송신에 관여하지 않는다.
CAN 트랜시버가 버스에 데이터를 보낼 때,
0을 전송하기 위해 High에 5V, Low에 1.1V를 건다.
1을 전송하기 위해 High에 2.5V, Low에 2.5V를 건다.
0 V (bit 0 수신, Logical low)
3.3 V (bit 1 수신, Logic high)
CAN High
5 V
2.5 V
CAN Low
1.1 V
2.5 V
즉, CAN High가 CAN Low보다 높아지면 AND 회로를 거치면서 0이 된다.
따라서 특정 기기에서 CAN High에 높은 전압을 걸게 되면 AND 로직에 의해 해당 시간대에 같이 전송되는 모든 Logical High 신호를 무시하고 Logical Low 신호만 전송되게 된다. 이것이 Logical Low(비트 0)를 우성 비트라고 부르는 이유이다.
이 우성 열성 원리를 통해 식별자(ID) 숫자가 낮은 기기의 메시지가 먼저 송신되는데, 이게 CAN 통신의 가장 큰 특징이다. 따라서 CAN 통신은 식별자 숫자가 낮을 수록 우선순위가 높은 특징을 갖는다.
CAN 트랜시버는 버스 상태를 계속 청취하며, recessive bit를 보내보며 dominant 상태를 확인하고, 11번 연속 recessive state가 지속되면 버스가 유휴(idle)상태라고 판단하여 다시 송신을 시도한다.
CAN 트랜시버에서 CAN 리시버로 버스 신호가 다시 전달되고, CAN 컨트롤러에서 버스 상태를 확인하여 제어하게 된다.
이러한 전압차를 이용한 차동 방식은 노이즈가 들어와도 두 가닥 모두에 똑같이 영향을 받기 때문에 안전하다.

CAN Frame의 구조

name
크기
설명
Start of Frame
1 bit
- 가장 앞에 나오는 dominant bit 로 데이터 프레임의 시작을 알린다. - 송신측과 수신측의 동기화에도 사용되는데, 기본 1 상태인 버스 선이 0이 되는 순간을 기준으로 동기화를 한다.
Arbitration Field
12 bit
- Identifier (11 bits for Standard CAN) : data frame의 priority를 결정하는 메시지 ID가 들어간다. ID 값이 작을수록 우선순위가 높다. - RTR (1 bit) : Remote Transmission Request. 해당 프레임이 Data Frame인지 Remote Frame 인지 나타낸다. - Dominant(0) for Data Frame - Recessive(1) for Remote Frame
Control Field
6 bit
- IDE : frame format 이 standard 인지 extended 인지 나타낸다. - Dominant(0) for Standard CAN - Recessive(1) for Extended CAN - Reserved (1 bit) : dominant(0) 값을 가진다. - DLC (4 bits) : Data Length Code
Data Field
0-8 bytes
메시지 내용이 들어있는 부분이다.
CRC Field
16 bits
- CRC (15 bits) : Receiving end에서 Error detection에 사용하며 checksum은 CAN Controller가 자동으로 계산해서 붙이므로 직접 신경쓸 필요는 없다. - CRC Delimiter : recessive(1) 값을 가진다.
ACK
2 bits
- Acknowledge Slot bit (1 bit) : Receiving node에 의해 피드백되는 bit로 수신자는 Frame의 CRC가 매치되고 문제없이 잘 수신(ACK)한 경우 해당 bit를 dominant(0)로 set 한다. 한편, Transmitter 입장에선 이 bit 가 dominant(0) 상태면 송신에 성공했다고 판단할 수 있고, recessive(1)인 경우에는 에러가 있다고 판단하고 자동으로 재전송한다. - Acknowledge Delimiter (1 bit) : recessive(1) 값을 가진다.
EOF
7 bits
현재 프레임의 끝을 나타내는 필드로 그 값은 전부 recessive(1) 값을 가진다.
IFS
3 bits
Inter Frame Spacing. 해당 비트 이후로 BUS는 IDLE 상태가 된다.
Acknowledge Delimiter (1) + EOF (7) + IFS (3) 합쳐서 11비트가 recessive(1) 상태면 BUS가 유휴 상태인 것으로 볼 수 있다.

Data Frame vs Remote Frame

RTR 비트가 0인 경우 Data Frame임을 나타내며, 데이터가 들어있다는 의미이다.
RTR 비트가 1인 경우 Remote Frame을 나타내며, 정보를 요청한다는 의미이다. 이 프레임을 수신한 노드는 필요한 정보를 전송하게 된다.

CANopen

순수 CAN 통신만을 이용하고자 한다면 각 기기의 펌웨어에는 message ID에 따른 처리 방법이 정의된 테이블이 들어있어야 하고, 모든 기기가 이를 공유해야 할 것이다. 따라서 기본적으로 메시지를 보낸 기기가 무엇인지 알 수 없다.
또한 CAN은 응답-요청 구조의 프로토콜이기 때문에 실시간 데이터 전송이 어려운 등의 문제가 발생하는데, 이를 해결하기 위해 L7 계층에서 구현한 것이 CANopen이다.
CANopen은 아래 포스팅에 정리해두었다.

References

관련 문서