mcp251xfd FIFO overflow, can0에서 RX가 떨어질 때 먼저 볼 것
mcp251xfd FIFO overflow는 MCP2517FD·MCP2518FD 계열 컨트롤러의 수신 FIFO가 가득 차서, 드라이버가 다음 프레임을 읽기 전에 들어온 CAN 프레임이 손실될 수 있다는 뜻입니다. 먼저 can0 통계와 CAN 에러 프레임, dmesg, IRQ 카운터를 같은 시간대에 확인하고, 그 결과를 기준으로 SPI 처리 지연·IRQ와 CPU 부하·CAN 설정과 배선을 나눠서 봐야 합니다.
이 글에서는 can0 fifo overflow를 컨트롤러, mcp251xfd spi0.0에 연결된 SPI 경로, Linux 커널, 애플리케이션 순서로 분리해서 확인하고, 특정 보드의 측정값이나 재현 결과를 전제로 하지 않은 채 로그와 통계를 읽는 방법을 정리하겠습니다.
mcp251xfd FIFO overflow는 정확히 무엇을 뜻할까?
한 줄 답: 칩 내부의 RX FIFO가 가득 차서 드라이버가 비우기 전에 도착한 이후 프레임을 받지 못했다는 뜻입니다.
CAN 프레임은 먼저 MCP2517FD·MCP2518FD 컨트롤러의 수신 FIFO에 들어가고, mcp251xfd 드라이버가 SPI로 FIFO 내용을 읽어 Linux의 SocketCAN 네트워크 경로에 전달합니다. 유입 속도가 FIFO를 비우는 속도보다 잠시라도 빠르면 FIFO가 찰 수 있고, 이때 overflow 이벤트와 RX 손실이 함께 나타날 수 있습니다.
이 메시지만으로 종단저항이나 비트레이트가 틀렸다고 단정하면 안 됩니다. 유효한 프레임이 많이 들어오는 상황에서 SPI·IRQ 처리가 늦어진 것일 수도 있고, 버스 오류와 재전송으로 처리해야 할 이벤트가 늘어난 것일 수도 있으니 먼저 두 종류의 신호를 분리해야 합니다.
드라이버가 RX overflow 인터럽트를 다룰 때는 컨트롤러의 RXOVIE 관련 이벤트가 단서가 될 수 있습니다. 다만 레지스터 이름이 로그에 그대로 찍히지 않을 수도 있으니까, RXOVIE가 보이지 않는다고 overflow가 없다고 판단하지 말고 네트워크 통계와 커널 로그를 함께 비교하면 됩니다.
CAN 컨트롤러·SPI·커널·애플리케이션 중 어느 구간에서 RX가 밀릴까?
한 줄 답: CAN 버스 → 컨트롤러 RX FIFO → SPI 읽기 → 커널 IRQ·드라이버 → SocketCAN 소켓 → 애플리케이션의 어느 경계에서 대기열이 쌓였는지 나눠 봐야 합니다.
컨트롤러 FIFO에서 이미 overflow가 발생했다면 애플리케이션이 프레임을 빠르게 읽는지만 고쳐서는 과거에 잃은 프레임을 되살릴 수 없습니다. 반대로 컨트롤러와 커널 통계는 안정적인데 애플리케이션이 일부 메시지를 놓친다면, 소켓 수신 큐와 애플리케이션의 read 처리 주기처럼 더 아래 단계의 문제일 수 있습니다.
can0는 Linux 네트워크 인터페이스이고, SPI 장치 경로인 spi0.0은 컨트롤러에 접근하는 하드웨어 경로를 가리킵니다. SocketCAN이 CAN 컨트롤러를 Linux 네트워크 장치로 올리는 구조와 임베디드 Linux에서 드라이버 경계를 이해하려면 임베디드 시스템이란 무엇이고 어떤 것을 프로그래밍하는지도 한 번 참고하면 좋습니다.
구간을 나눌 때는 “RX dropped가 보였다”는 사실만으로 애플리케이션 원인이라고 결론 내리지 말고, 컨트롤러 overflow 로그가 있었는지, 해당 시점에 IRQ가 처리됐는지, 에러 프레임이 동반됐는지 순서대로 맞춰 봐야 합니다. 이 상관관계를 잡으면 SPI 문제와 CAN 물리계층 문제를 같은 증상으로 뭉뚱그리지 않게 됩니다.
overflow를 발견했을 때 가장 먼저 어떤 명령어를 입력할까?
한 줄 답: 로그·인터페이스 통계·CAN 에러 프레임·IRQ 카운터를 같은 시점에 수집하는 것부터 시작하면 됩니다.
dmesg | grep -iE 'mcp251xfd|can0|fifo|overrun'
ip -details -statistics link show can0
candump -e any,0:0,#FFFFFFFF
cat /proc/interrupts | grep -i can
overflow가 반복되는 순간이라면 네 명령을 순서대로 한 번씩만 실행하기보다, candump는 별도 터미널에서 계속 실행하고 나머지 결과를 전후로 남기는 편이 좋습니다. 인터페이스를 내렸다가 올리거나 장치를 재시작하면 누적 통계와 직전 로그를 바꿀 수 있으니까, 가능한 한 현재 상태를 먼저 기록해야 합니다.
candump가 설치되지 않았거나 권한이 없으면 그 사실도 기록해 두어야 합니다. 에러 프레임을 못 봤다는 결과와 에러 프레임이 실제로 없었다는 결과는 다르기 때문입니다.
ip -details -statistics link show can0의 RX dropped·overrun·errors·bus-off는 어떻게 해석할까?
한 줄 답: RX dropped와 overrun의 증가 여부는 수신 경로 포화를 찾는 단서이고, errors와 bus-off의 증가는 CAN 오류 상태를 별도로 확인하라는 신호입니다.
ip -details -statistics link show can0의 카운터는 보통 인터페이스가 올라온 뒤 누적되니까, 절대값 하나보다 같은 간격을 두고 다시 실행했을 때 어떤 값이 증가하는지가 중요합니다. RX dropped가 늘었다면 프레임이 인터페이스 수신 경로 어딘가에서 버려졌다는 뜻으로 볼 수 있지만, 그 숫자 하나만으로 컨트롤러 FIFO에서 버려졌다고 확정할 수는 없습니다.
overrun이 함께 증가하면 장치나 드라이버가 들어오는 수신 데이터를 제때 처리하지 못했을 가능성이 커집니다. 이때 dmesg의 mcp251xfd·FIFO 관련 메시지와 SPI·IRQ 상태를 같은 구간에서 비교하면 하드웨어 FIFO 포화 쪽의 우선순위를 판단하는 데 도움이 됩니다.
errors는 인터페이스 수준의 오류 누계이고, CAN 에러 프레임의 종류를 대신 보여 주는 상세 진단 결과는 아닙니다. bus-off는 CAN 컨트롤러가 오류 누적으로 버스에서 빠진 상태를 뜻하니까, FIFO overflow와 같은 현상이라고 보지 말고 비트레이트·FD 설정·배선·트랜시버를 함께 확인해야 합니다.
예를 들어 RX dropped와 overrun만 재현 구간에서 늘고 에러 프레임이나 bus-off가 보이지 않는다면 수신 경로의 drain 지연을 먼저 볼 수 있습니다. 반대로 bit·format·CRC·ACK 계열 에러와 errors가 같은 시각에 늘면 물리·프로토콜 오류가 트래픽과 처리 부담에 영향을 줬는지부터 확인하는 식으로 우선순위를 세우면 됩니다.
candump -e any,0:0,#FFFFFFFF로 CAN 에러 프레임은 어떻게 볼까?
한 줄 답: 이 명령은 모든 CAN 인터페이스의 에러 메시지 프레임을 실시간으로 보고, 출력 시각을 overflow와 같은 타임라인에 놓는 데 사용합니다.
candump -e any,0:0,#FFFFFFFF
여기서 -e는 에러 프레임 표시를 요청하고, any는 모든 CAN 인터페이스를 대상으로 합니다. 특정 인터페이스만 보고 싶다면 수집 범위를 좁힐 수 있지만, 처음 원인을 찾을 때는 can0 외의 인터페이스에서 온 오류가 섞였는지도 확인해야 합니다.
Linux SocketCAN 공식 문서는 물리 계층과 MAC 계층에서 감지된 문제를 진단하려면 Error Message Frames를 정확한 타임스탬프와 함께 기록해야 한다고 설명합니다. 이 오류 프레임 수신은 기본적으로 꺼져 있고, CAN raw 소켓에서는 CAN_RAW_ERR_FILTER로 원하는 오류 종류를 요청하는 구조입니다.
따라서 candump 출력에 찍힌 수신 시각과 dmesg의 overflow 시각을 맞춰 봐야 합니다. ACK·비트·형식·CRC·bus-off처럼 버스 상태를 설명하는 오류가 같은 구간에 반복되면 배선과 CAN 설정을 먼저 점검하고, 에러 프레임은 조용한데 유효 프레임이 몰릴 때만 overflow가 늘면 SPI·IRQ·CPU 처리 여유를 먼저 의심하면 됩니다.
에러 프레임이 화면에 안 나온다고 버스가 정상이라는 뜻은 아닙니다. 그 순간 오류가 없었거나, 드라이버·컨트롤러가 보고하지 않았거나, 필터와 수집 범위가 맞지 않았을 수도 있으니까 candump의 부재를 단독 증거로 사용하지 않아야 합니다.
dmesg와 인터럽트 통계에서는 무엇을 비교해야 할까?
한 줄 답: overflow 로그가 발생한 시간에 mcp251xfd의 IRQ가 실제로 처리됐는지, 다른 작업과 IRQ에 밀리고 있지는 않은지를 비교하면 됩니다.
먼저 dmesg에서 mcp251xfd, can0, fifo, overrun이 포함된 줄을 시간 순서로 모아 봅니다. overflow나 복구 메시지가 반복되는 간격과 candump 에러 프레임이 나타나는 간격을 맞추면, 커널이 감지한 현상이 버스 오류 직후인지 단순한 수신 처리 지연인지 구분하는 데 도움이 됩니다.
/proc/interrupts의 값은 누적 카운터라서 한 번 읽은 숫자보다 짧은 동일 구간의 전후 차이를 봐야 합니다. grep -i can에 결과가 없더라도 IRQ 이름이 반드시 can이라는 보장은 없으니까, 그것만으로 인터럽트가 연결되지 않았다고 단정하지 말고 장치 트리·커널 로그와 함께 IRQ 라벨을 확인해야 합니다.
overflow가 재현되는 동안 해당 IRQ 카운터가 전혀 변하지 않거나 예상보다 늦게 증가하면 IRQ 매핑·마스킹·스케줄링 지연을 점검할 후보가 됩니다. 카운터는 정상적으로 증가하지만 SPI 전송이나 CPU 사용이 밀린다면, IRQ가 들어온 뒤 실제 FIFO read가 늦어지는 경로를 더 살펴봐야 합니다.
SPI 속도·IRQ·CPU 부하는 FIFO overflow와 어떻게 연결될까?
한 줄 답: SPI 읽기 한 번이 늦거나 IRQ 처리가 지연되면 컨트롤러 RX FIFO를 비우는 간격이 길어지고, 그 사이 프레임이 쌓여 overflow가 날 수 있습니다.
mcp251xfd spi0.0은 SPI를 통해 컨트롤러 레지스터와 FIFO 데이터를 읽는 경로니까, SPI 클록이 낮거나 다른 SPI 장치와 버스를 공유해 전송이 지연되면 수신 drain 속도가 떨어질 수 있습니다. 다만 SPI 클록을 무조건 올리는 방식은 안전한 해결책이 아니고, 컨트롤러 데이터시트·보드 배선·SPI 모드·커널의 장치 설정이 허용하는 범위 안에서 검증해야 합니다.
IRQ가 들어와도 CPU가 높은 부하로 바쁘거나 인터럽트 처리가 오래 막혀 있으면 드라이버의 FIFO read가 늦어질 수 있습니다. 이 경우에는 overflow가 발생한 시간대의 CPU 작업, IRQ 카운터, SPI 전송 지연을 함께 봐야 하고, 특정 CPU 사용률이나 지연 수치를 측정한 것처럼 쓰면 안 됩니다.
애플리케이션이 느린 것과 컨트롤러 FIFO가 넘치는 것도 분리해야 합니다. 커널이 프레임을 소켓으로 넘긴 뒤 애플리케이션이 늦게 읽는 상황은 소켓 수신 큐 문제일 수 있지만, IRQ에서 컨트롤러 FIFO를 읽는 단계가 늦다면 애플리케이션 코드를 고치는 것만으로는 해결되지 않습니다.
CAN 비트레이트·종단저항·버스 부하는 왜 함께 점검해야 할까?
한 줄 답: 잘못된 CAN 설정이나 물리계층 오류는 에러와 재전송을 늘리고, 높은 버스 부하는 유효 프레임의 유입 속도를 높여 FIFO가 포화될 여유를 줄일 수 있습니다.
먼저 can0의 arbitration bitrate, CAN FD를 쓴다면 data bitrate와 FD 활성화 상태가 다른 노드와 맞는지 확인합니다. 한쪽의 비트레이트나 FD 설정이 다르면 bit·form·CRC·ACK 관련 오류와 bus-off가 나타날 수 있고, 이때 보이는 RX dropped를 SPI 문제로만 해석하면 원인을 놓치게 됩니다.
종단저항은 버스 양 끝의 구성, 배선 길이와 토폴로지, 트랜시버 전원과 신호 상태를 함께 봐야 합니다. 종단이나 배선이 맞지 않으면 특정 프레임 구간에서 물리 오류가 반복될 수 있으니까, 에러 프레임의 종류와 발생 시각을 실제 배선 점검 결과와 맞춰야 합니다.
에러 프레임이 거의 없는데 높은 프레임 유입 구간에서만 can0 fifo overflow가 늘면 순수한 버스 부하와 수신 처리 여유를 비교할 차례입니다. 반대로 오류와 재전송이 함께 늘면 먼저 버스 조건을 안정화한 다음 같은 부하에서 FIFO 통계를 다시 수집해야 합니다. 이때 프레임 손실률이나 처리량을 측정하지 않았다면 임의의 숫자로 결론을 만들지 않아야 합니다.
원인별로 어떤 조치를 적용해야 할까?
한 줄 답: 관찰된 신호에 맞는 한 구간만 먼저 조정하고, 변경 뒤 같은 명령으로 overflow·에러 프레임·IRQ 증가 여부를 다시 비교해야 합니다.
| 원인 후보 | 함께 확인할 신호 | 적용할 조치 | 판단할 때 주의할 점 |
|---|---|---|---|
| 컨트롤러 RX FIFO가 제때 비워지지 않음 | RX overflow 관련 로그, RX dropped·overrun 증가 | IRQ 연결과 드라이버 상태를 확인하고, overflow가 발생한 구간의 FIFO read 경로를 추적합니다 | RX dropped 하나만으로 칩 FIFO 손실이라고 확정하지 않습니다 |
| SPI 전송 지연 또는 버스 경합 | spi0.0 경로, 공유 SPI 장치, overflow 시각의 전송 지연 | SPI 모드와 장치 설정을 확인하고, 데이터시트와 보드가 허용하는 범위에서 속도·경합을 조정합니다 | 특정 SPI 클록 값이 모든 보드의 해결책은 아닙니다 |
| IRQ·CPU 처리 지연 | IRQ 카운터 변화, dmesg 시각, 동시 CPU 부하 | IRQ 매핑·마스킹과 스케줄링을 확인하고 불필요한 CPU·IRQ 부담을 줄입니다 | 측정하지 않은 CPU 사용률이나 지연을 가정하지 않습니다 |
| SocketCAN·애플리케이션 소비 지연 | 커널 수신 통계는 안정적이지만 애플리케이션에서 누락 | 소켓 read 루프와 블로킹 작업, 수신 큐 처리 순서를 점검합니다 | 이 경우를 컨트롤러 FIFO overflow의 원인으로 곧바로 부르지 않습니다 |
| 비트레이트·CAN FD 설정 불일치 | bit·form·CRC·ACK 계열 에러, errors·bus-off 증가 | arbitration/data bitrate, FD 모드와 노드 설정을 맞춥니다 | 에러 프레임 없이 설정 오류라고 단정하지 않습니다 |
| 종단·배선·트랜시버 문제 | 물리계층 에러가 특정 시각에 반복 | 양 끝 종단, 배선 토폴로지, 전원·접지와 트랜시버를 점검합니다 | FIFO 통계만으로 물리 원인을 확정하지 않습니다 |
| 버스 부하가 처리 여유를 초과 | 에러는 적지만 유효 프레임이 몰릴 때 overflow 증가 | 송신 주기·우선순위·불필요한 트래픽과 수신 처리 경로를 함께 조정합니다 | 부하율·손실률은 실제 측정값이 있을 때만 말합니다 |
| MCP2518FD FIFOCI 관련 별도 이슈 | 특정 실리콘·커널 조합에서만 나타나는 재현 조건 | 해당 erratum과 사용 중인 커널의 우회 패치 적용 여부를 별도로 확인합니다 | DS80000789E 항목 6을 일반적인 FIFO overflow의 원인이나 만능 해결책으로 보지 않습니다 |
실제 조치 순서는 ip -details -statistics link show can0의 증가 카운터를 기준으로 잡고, candump의 에러 프레임 시각과 dmesg·IRQ 변화를 겹쳐 보는 방식입니다. 버스 오류가 확인되면 비트레이트와 배선을 먼저 안정화하고, 오류 없이 RX 경로만 포화되면 SPI·IRQ·CPU·소켓 소비 순서로 범위를 좁히면 됩니다.
변경을 적용한 뒤에는 인터페이스를 재시작한 직후의 누적값을 새 기준으로 삼고, 같은 부하에서 네 명령을 다시 수집합니다. 숫자가 줄었다는 이유만으로 해결을 확정하지 말고, overflow 로그가 사라졌는지와 에러 프레임의 타임스탬프가 함께 달라졌는지까지 확인해야 합니다.
도구 구독이 부담되면 할인 경로만 보면 됩니다.