본문 바로가기

CAN

7. 오류 검출과 오류 상태

프레임 모니터링 과정에서 검출될 수 있는 오류들과 그 범위는 다음과 같습니다.



can data frame rtr ide staff error bit crc acr form


인식 주체

오류 종류

내용

송신 노드

비트 오류

송신하고 있는 비트값과 다른 값을 검출했을 때 발생하며, STM32는 비트 오류를 비트 도미넌트 오류와 비트 리세시브 오류로 나누고 있습니다. 하지만 비트 도미넌트 오류가 도미넌트 비트를 송신했는데 리세시브 비트를 수신했다는 것인지 리세시브 비트를 송신했는데 도미넌트 비트를 수신했다는 것인지는 모르겠습니다.

인지 오류

송신 노드는 ACK 비트를 리세시브(1)로 보낸다고 했습니다. 그래도 자신은 도미넌트(0)를 수신할 것으로 예상하고 있습니다. 이때 도미넌트 비트를 수신하지 못한 경우 발생합니다.

수신 노드

스태프 오류

동일한 비트가 연속으로 6비트 이상 수신된 경우 발생합니다.

CRC 오류

자신이 계산한 CRC 값과 수신된 CRC 값이 다른 경우에 발생합니다.

폼 오류

모든 프레임에서 무조건 도미넌트 또는 리세시브로 정의된 비트에서 다른 값이 검출될 경우 발생합니다. 그런데 SOF 비트나 RTR, IDE 비트는 외 폼 오류 범위에서 제외된 걸까요? 오류 검출은 버스에서 프레임이 검출될 때 수행합니다. 그런데 다른 노드는 SOF를 인식했는데 어떤 노드만 SOF를 인식하지 못했다면 그 노드는 아직 버스가 유휴 상태인 것으로 판단하고 오류 검출조차 수행하지 않을 것입니다. 그리고 위에서 예로든 프레임은 표준 식별자를 사용하는 데이터 프레임 입니다. 표준 식별자를 사용하는 데이터 프레임에선 RTR비트와 IDE가 무조건 0/0이지만 다른 프레임에선 다른 고정값을 갖기 때문에 폼 오류 범위에서 제외됩니다.


CAN 프로토콜은 프레임 모니터링 과정에서 오류를 검출하면 오류 카운트를 증가시키도록 규정하고 있습니다. 증가되는 카운트 값은 오류 내용마다 다릅니다. 그리고 전송을 1회 성공할 때마다 오류 카운트를 1씩 감소시킵니다. 이 오류 카운터는 송신 오류 카운터와 수신 오류 카운터가 따로 구성되어 있으며, 오류 카운터에 따른 CAN 컨트롤러의 상태는 다음과 같습니다.


can monitoring error rec tec passive active



리셋시 CAN 컨트롤러는 에러 엑티브 상태입니다. 상태에 에러가 들어간다고 무조건 이상이 있는 것은 아닙니다. TEC (Transmit Error Count) 또는 REC (Receive Error Count)127보다 커지면 에러 페시브 상태로 진입합니다. 하지만 에러 페시브 상태라고 해도 CAN 컨트롤러는 여전히 네트워크에 참여하고 있습니다. 전송에 성공하면 TEC1씩 감소하고 수신에 성공하면 REC1씩 감소합니다. 계속 감소해서 TEC REC 모두 128보다 작아지면 다시 에러 엑티브 상태로 전환합니다. 전송에 계속 실패해서 TEC255를 초과하면 버스 오프 상태가 됩니다. REC는 상관없습니다. CAN 버스에서 리세시브를 11비트씩 128회 감지하면 에러 엑티브 상태가 되어 다시 네트워크에 참여할 수 있습니다.


STM32 CAN 컨트롤러는 오류 탐지 및 오류 카운트에 대한 인터럽트 소스를 제공하지만 위에 나와있는 CAN 프로토콜에서 규정한 카운트와 그에 따른 상태와 정확히 일치하지 않습니다.


REC 또는 TEC127을 초과하면 CAN_ESR (Error State) 레지스터의 EPVF (Error Passive Flag) 비트가 셋되고, TEC255를 초과하면 버스 오프가 되면서 BOFF (Bus Off Flag) 비트가 셋되는 것은 CAN 프로토콜과 동일하지만, STM32 CAN 컨트롤러는 REC 또는 TEC96이상이 되면 오류에 대한 경고의 의미로 CAN_ESR 레지스터의 EWGF 비트가 셋합니다.


프레임에서 오류를 탐지할 경우 CAN_ESR 레지스터의 LEC (Last Error Code) 필드에 오류 발생 여부와 오류의 내용을 표시합니다. 이 필드가 0일 경우에만 오류가 없는 상태이며, 그 외의 경우는 오류 내용에 따라 값이 달라집니다. 자세한 내용은 RM0091 849페이지에서 확인할 수 있습니다. STM32 CAN 컨트롤러는 위에서 설명한 비트 오류에 대해 비트 도미넌트 오류와 비트 리세시브 오류로 구분하고 있는데, 비트 도미넌트 오류가 도미넌트 비트를 송신했는데 리세시브 비트를 수신했다는 것인지 리세시브 비트를 송신했는데 도미넌트 비트를 수신했다는 것인지는 모르겠습니다. 확인하려면 오실로스코프를 다른 과에서 다시 빌려야 하는데, 매번 빌리기도 뭐해서 다음에 기회가 되면 실험해서 올리겠습니다.


CAN_ESR의 오류 플래그가 셋되었을 때 인터럽트를 발생시킬 수 있습니다. 하지만 이 오류 플래그는 직접 인터럽트 소스가 될 수 없습니다. CAN_IER (Interrupt Enable) 레지스터에서 EWGIE, EPVIE, BOFIE, LECIE 비트를 셋하여 대응하는 CAN_ESR의 오류 플레그를 CAN_MSR 레지스터의 ERRI비트와 연결시킵니다. , CAN_IER 레지스터의 LECIE 비트와 EWGIE 비트를 셋하면, 프레임에서 오류가 탐지되었을 경우 또는 TEC/REC96이상이 되었을 경우 CAN_MSR 레지스터의 ERRI 비트가 셋됩니다. 그리고 CAN_IER 레지스터에서 ERRIE 비트를 셋하여 이 ERRI 비트를 인터럽트 소스로 만들 수 있습니다. 이에 대한 직관적인 그림은 RM0091 839페이지에서 확인할 수 있습니다.