| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 |
- i.MX8MP
- bus-off
- TIM17
- xHCI
- 44.1kHz
- 커스텀 보드
- EASRC
- CAN 필터
- can-utils
- 임베디드
- 타임베이스
- 리눅스 커널
- CAN FD
- can_filter
- SocketCAN
- HAL_Delay
- restart-ms
- PTN5150A
- Azure RTOS
- CC 로직
- error-passive
- EILSEQ
- 임베디드 오디오
- assigned-clocks
- 오디오 클럭
- 리눅스 CAN
- vcan
- fsl-sai
- 임베디드 리눅스
- 하드웨어 디버깅
- Today
- Total
임베디드 일기장
리눅스 CAN bus-off 상태 복구 — restart-ms 자동 복구 본문
CAN 컨트롤러는 에러가 누적되면 스스로 버스에서 물러난다. 이 보호 메커니즘(error confinement)의 종착역이 bus-off 상태인데, 여기 들어가면 송수신이 완전히 멈추고 저절로 돌아오지 않는다(설정하지 않는 한). 이 글은 리눅스에서 bus-off를 진단하고 복구하는 방법을 정리하고, 후반부에서는 CAN 하드웨어가 없는 개발 PC에서 상위 스택을 테스트하는 vcan 환경 구성을 다룬다.
1. CAN 에러 상태머신 복습
CAN 노드는 TEC/REC(송신/수신 에러 카운터)에 따라 세 상태를 오간다.
Error-Active (정상: 에러 프레임을 dominant로 송출 가능)
↓ 카운터 > 127
Error-Passive (경고: 통신은 되지만 에러 프레임이 recessive, 송신 후 대기시간 증가)
↓ TEC > 255
Bus-Off (퇴출: 송수신 불가)핵심은 bus-off가 일시적 상태가 아니라 종착 상태라는 것. 표준상 복구 조건(128×11 recessive bit 관찰)이 충족돼도, 컨트롤러/드라이버가 재시작 절차를 밟아야 버스로 돌아온다.
2. 상태 확인
ip -details -statistics link show can0
볼 것: state 필드(ERROR-ACTIVE / ERROR-PASSIVE / BUS-OFF), restarts 카운터(자동 복구 횟수), 그리고 berr-counter tx rx의 에러 카운터 값. 상태 전이를 실시간으로 잡고 싶으면 에러 프레임 수신 소켓을 열거나 candump로 관찰한다.
candump -e any,0:0,#FFFFFFFF # 에러 프레임 포함 덤프
3. 복구 방법 세 가지
① 수동: 인터페이스 재시작
ip link set can0 down
ip link set can0 up type can bitrate 500000
가장 확실하지만, down/up 과정에서 소켓들이 영향을 받고 애플리케이션 재연결 처리가 필요하다.
② 수동: restart 트리거 — 인터페이스를 내리지 않고 bus-off 복구만 지시할 수 있다.
ip link set can0 type can restart
단, 이 명령은 bus-off 상태일 때만 유효하다(아닐 때 실행하면 에러).
③ 자동: restart-ms (실전 권장) — bus-off 진입 후 지정 시간(ms)이 지나면 드라이버가 자동으로 복구를 수행한다.
ip link set can0 down
ip link set can0 up type can bitrate 500000 restart-ms 100
무인 장비라면 사실상 필수 설정이다. 흔한 오해 하나를 짚자면, 이 설정은 소켓 옵션(setsockopt)이 아니라 netlink(ip link) 레벨의 인터페이스 속성이다. 애플리케이션 코드가 아니라 인터페이스 초기화 스크립트에 들어가야 할 값이라는 뜻이다.
주의: 자동 복구는 증상 치료다. bus-off까지 간 근본 원인 — 종단저항 누락, 비트레이트 불일치, 배선 문제, 특정 노드의 고장 — 을 잡지 않으면 "복구 → 재진입"을 무한 반복하며 버스를 계속 오염시킨다. restarts 카운터가 계속 증가하고 있다면 복구 설정이 문제를 가리고 있는 것이니 에러 카운터 추이와 함께 원인 조사를 해야 한다. 원인 규명에는 앞서 쓴 에러 전용 raw 소켓(CAN_RAW_ERR_FILTER) 상시 감시가 유용하다.
4. 하드웨어 없이 스택 테스트: vcan
CAN이 없는 리눅스 PC에서도 SocketCAN 상위 계층은 전부 테스트할 수 있다. vcan(가상 CAN 인터페이스) 은 루프백 기반 가상 네트워크 장치라서, raw 소켓, ISO-TP, BCM, 자체 프로토콜 로직까지 하드웨어 없이 돌려볼 수 있다.
sudo apt install can-utils
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0
# 터미널 1
candump vcan0
# 터미널 2
cansend vcan0 123#11223344
가능/불가능의 경계를 분명히 하면: SocketCAN API, ISO-TP 커널 모듈, 필터링, 애플리케이션 프로토콜 검증은 가능. 반면 실제 컨트롤러 드라이버(flexcan 등)의 probe/인터럽트/비트타이밍, 그리고 이 글 전반부의 bus-off 상태 전이 자체는 재현 불가다 — vcan에는 에러 카운터 개념이 없다. 즉 vcan은 "프로토콜 로직 개발용"이고, 에러 처리 경로 검증은 결국 실물(또는 에러 프레임을 주입할 수 있는 장비)이 필요하다.
WSL2 주의사항: WSL2 기본 커널에는 vcan 모듈이 빠져 있어 modprobe vcan이 실패한다. 선택지는 세 가지 — WSL2 커널을 직접 빌드해 CONFIG_CAN/CONFIG_CAN_VCAN을 켜거나, VirtualBox/QEMU의 정식 리눅스 VM을 쓰거나, 개발 보드에서 직접 vcan을 쓰는 것. 커널 빌드가 익숙하다면 WSL2 커널 교체도 할 만하지만(커널 소스에 컨피그 추가 후 .wslconfig로 지정), 한 번 해보는 실험이 아니라면 보드에서 직접 하는 게 결국 편했다.
5. 정리
- bus-off는 종착 상태다 — 복구는 down/up,
restart트리거,restart-ms자동 복구 중 택일 restart-ms는 소켓 옵션이 아니라 ip link 인터페이스 속성이다 — 초기화 스크립트에 넣어라- 자동 복구를 걸었어도
restarts카운터 증가는 근본 원인이 살아 있다는 경보다 - vcan으로 프로토콜 로직은 하드웨어 없이 개발 가능하지만, 에러 상태머신은 재현되지 않는다
- WSL2에서는 vcan이 기본 불가 — 커널 재빌드 또는 VM/실보드로
CAN 시스템의 버스 에러 대응 설계 과정에서 정리한 내용입니다.