i2cdetect / i2cget 사용법, 센서 주소를 어떻게 확인하나

한 줄 답: i2c-dev가 만든 /dev/i2c-N에 대해 i2cdetect -l로 버스를 고르고, i2cdetect로 슬레이브 주소를 스캔한 다음 i2cget으로 레지스터 값을 읽습니다.

이 글은 커널 Implementing I2C device drivers in userspace(Documentation/i2c/dev-interface.rst)와 i2c-tools의 i2cdetect(8)/i2cget(8)을 기준으로 한 userspace 스캔·읽기 howto입니다. 디바이스트리 작성법이나 libgpiod 글은 다시 서술하지 않습니다.

버스 번호는?

한 줄 답: 어댑터 번호는 동적으로 붙으므로 i2cdetect -l 또는 /sys/class/i2c-dev/로 지금 부팅의 버스 목록을 확인한 뒤, 그 번호(또는 이름)를 i2cdetect/i2cget에 넘깁니다.

커널 문서에 따르면 보통 장치는 커널 드라이버가 다루지만, 모듈 i2c-dev를 올리면 어댑터마다 userspace 문자 장치 /dev/i2c-0, /dev/i2c-1, …(major 89)가 생깁니다. 번호는 부팅마다 바뀔 수 있어 “항상 1번”이라고 가정하면 안 됩니다.

# 어댑터 목록
i2cdetect -l

# 예: 버스 1의 표준 주소 범위를 즉시 스캔(-y는 확인 프롬프트 생략)
i2cdetect -y 1

출력 칸의 의미(i2cdetect(8)):

  • -- : 프로브했으나 응답 없음
  • UU : 커널 드라이버가 이미 사용 중이라 프로브를 건너뜀(해당 주소에 칩이 있을 가능성이 큼)
  • 2d 같은 16진수 : 응답하는 칩을 찾음

기본 스캔 범위는 대략 0x08–0x77입니다. SMBus quick write / receive byte로 프로브하므로 버스를 혼란시키거나 데이터 손실을 일으킬 수 있다는 경고가 man 페이지에 있습니다. -q/-r는 권장되지 않는 강제 프로브 방식입니다.

주소를 알았다면 레지스터 읽기 예시는 다음과 같습니다(i2cget(8)).

# 버스 1, 칩 0x2d, 레지스터 0x11 (바이트 읽기, 확인 후 실행)
i2cget -y 1 0x2d 0x11

C API로는 /dev/i2c-N을 open한 뒤 ioctl(file, I2C_SLAVE, addr)로 주소를 고르고, i2c_smbus_* 또는 I2C_RDWR로 트랜잭션합니다. SMBus 헬퍼는 i2c-tools의 libi2c를 링크합니다. 인라인 때문에 -O 계열 최적화가 필요합니다(커널 문서 IMPORTANT).

권한이 없으면?

한 줄 답: /dev/i2c-*에 대한 읽기·쓰기 권한이 필요합니다. 보통 root이거나, 배포판이 장치를 i2c 그룹 등에 두는 경우 해당 그룹 멤버십·udev 규칙으로 맞춥니다.

권한 오류(EACCES 등)가 나면 장치 노드의 owner/group/mode를 확인합니다. i2cget -f는 이미 커널 드라이버가 점유한 장치에도 강제로 들어가며, man 페이지가 위험하다고 명시하므로 기본 경로로 쓰지 않습니다. UU가 보이는 주소는 드라이버가 이미 붙어 있다는 신호이므로, userspace에서 같은 주소를 건드리기 전에 커널 드라이버와의 역할을 먼저 정리하는 편이 안전합니다.

스크립트에서 -y는 확인 프롬프트를 건너뛰므로, 잘못된 버스 번호와 함께 쓰면 위험이 커집니다.

디바이스트리와 관계는?

한 줄 답: 디바이스트리는 보드에서 어떤 버스·슬레이브·드라이버 바인딩이 필요한지를 커널에 기술하고, /dev/i2c-* + i2c-tools는 이미 올라온 어댑터에 대한 userspace 접근 경로입니다. DT를 “대신 쓰는” 관계가 아닙니다.

실무에서 경계를 나누면 다음과 같습니다.

  • 커널 드라이버가 있어야 하는 장치: DT(또는 ACPI 등)로 바인딩하고 전용 드라이버가 sysfs/char-dev를 제공하는 쪽이 일반적입니다.
  • 스캔·초기 bring-up·드라이버 없는 실험: i2cdetect/i2cget과 I2C_SLAVE ioctl 경로가 문서화된 userspace 수단입니다.
  • 어댑터 존재: DT/플랫폼 코드가 I2C 컨트롤러를 등록해야 /dev/i2c-N이 생깁니다. userspace 스캔만으로 컨트롤러 자체를 만들어 내지는 않습니다.

이 글에서는 DT 문법·오버레이 절차는 다루지 않습니다. 주소 확인과 레지스터 읽기에 필요한 userspace 경계만 짚습니다.

FAQ

Q. /dev/i2c-*는 무엇인가?
A. i2c-dev가 노출하는 어댑터별 문자 장치입니다. 슬레이브 전용 노드가 아니라, ioctl로 주소를 고른 뒤 그 버스에서 트랜잭션합니다.

Q. plain read/write만으로 충분한가?
A. 커널 문서는 combined transaction(한 트랜잭션에 read+write)을 read/write로는 못 한다고 하며, 그래서 userspace는 거의 I2C_RDWR 또는 SMBus 헬퍼를 씁니다.

참고