서로 다른 버스의 주소를 같은 숫자로 생각하지 않습니다
| 버스 | 주소·선택의 대표 의미 | 주의할 점 |
|---|---|---|
| I²C | adapter와 slave address로 장치를 선택합니다. | 7비트 주소와 R/W bit까지 합친 8비트 전송 값을 구분합니다. |
| SPI | controller의 chip select로 대상을 고릅니다. | slave address가 I²C처럼 표준 packet에 포함된다고 가정하지 않습니다. |
| USB | host가 device·configuration·interface·endpoint를 관리합니다. | device address와 endpoint 번호, interface 번호는 다른 값입니다. |
| PCIe | bus/device/function과 BAR·DMA 주소 등을 사용합니다. | BAR의 CPU MMIO 주소와 장치가 RAM에 접근하는 DMA 주소를 구분합니다. |
버스가 발견됐다는 것은 통신 경로의 한 조건입니다. 장치가 필요한 전원·clock·reset 상태인지, driver가 맞는 protocol을 쓰는지까지 확인해야 합니다. I²C 사용자 인터페이스 SPI 사용자 인터페이스 PCI driver의 자원 처리
Jetson의 J12 핀 이름을 Linux 버스 번호로 읽지 않습니다
Jetson Orin Nano Developer Kit에서는 커넥터 핀 번호, 보드의 신호 이름, SoC 신호 이름, Linux의 논리 adapter 번호를 따로 대응시켜야 합니다. NVIDIA Carrier Board Specification SP-11324-001_v1.3의 J12 표(인쇄 페이지 21–23, PDF 페이지 25–27)는 다음처럼 표기합니다. 아래 숫자는 Linux 버스 번호를 보장하지 않습니다.

| J12 물리 핀 | 보드 신호 | 모듈 핀 | 사양서의 SoC 신호 이름 |
|---|---|---|---|
| 3 | I2C1_SDA | 191 | GP16_I2C8_DAT |
| 5 | I2C1_SCL | 189 | GP15_I2C8_CLK |
| 27 | I2C0_SDA | 187 | GP14_I2C2_DAT |
| 28 | I2C0_SCL | 185 | GP13_I2C2_CLK |
신호 이름에 있는 0·1·2·8을 그대로 /dev/i2c-N의 N에 넣지 않습니다. Linux v6.18.37의 I²C sysfs 설명에서 Linux 버스 번호는 논리 번호입니다. 하나의 물리 컨트롤러를 나타낼 수도 있고, I²C MUX 뒤의 채널을 나타낼 수도 있습니다. DT의 aliases가 번호를 지정할 수 있으며 MUX 채널은 등록 상태에 따라 번호를 배정받을 수도 있습니다.
번호를 추측하지 않고 연결 관계를 확인합니다
사양서로 실제 핀과 신호를 정한 다음, 사용하는 보드·BSP의 DT 노드 및 alias를 런타임 sysfs와 대조합니다. i2cdetect -l은 adapter 목록을 보는 옵션이며 주소 탐색 명령과 다릅니다. 각 /sys/bus/i2c/devices/i2c-N/ 아래의 name, device, of_node를 읽고, MUX가 있으면 mux_device와 MUX 장치의 channel-* 링크를 따라 상위 버스와 채널을 확인합니다. 이 과정에서 얻은 실제 N과 장치의 slave address는 다시 별개의 값입니다.
NVIDIA 포럼의 2025년 3월 JetPack 6.2 사용자 사례는 J12 핀 3·5에서 버스 7을, 27·28에서 버스 1을 보고합니다. 답변은 비교 대상 릴리스를 되묻고 기존부터 버스 7이었을 가능성을 언급합니다. 이는 그 사용자의 관측이지 “JetPack 6.2가 번호를 공식 변경했다”는 발표가 아닙니다. 다른 보드나 BSP에도 그 번호를 고정 적용하지 않습니다.
이 보완은 공식 핀 표와 Linux 식별 체계에 한정합니다. 인계에 포함된 원문 블로그는 이번 중앙 조회에서 HTTP 429로 본문을 확보하지 못했으므로 해당 글의 컨트롤러 주소·센서 실행 예를 검증된 결과로 재사용하지 않았습니다. 보드 연결, 주소 탐색, 센서 전송, DT 변경은 수행하지 않았습니다.
English: connector labels versus logical adapters
The v1.3 carrier specification distinguishes J12 pins, carrier labels and SoC signal names. None directly fixes Linux i2c-N. Resolve the running device-tree aliases and sysfs controller/mux topology instead. The JetPack 6.2 forum exchange is a user observation, not an official renumbering guarantee. No board test or sensor scan was performed; the unavailable original blog was not treated as centrally verified evidence.
I²C register 읽기는 장치의 protocol을 따릅니다
- 메시지 1
slave에 읽을 register 번호를 전송합니다.
필요한 경우 repeated START로 다음 메시지를 이어 갑니다.
- 메시지 2
같은 slave에서 지정 길이의 데이터를 읽습니다.
전송 결과와 길이를 확인합니다.
- 호출자
endianness와 bit field 규칙에 맞춰 값을 해석합니다.
화살표는 버스 메시지의 순서입니다. 모든 I²C 장치가 register 주소 쓰기+읽기 형태를 사용하는 것은 아닙니다.
별도의 write()와 read()는 중간에 STOP을 만들 수 있어 combined transaction과 다를 수 있습니다. 사용자 공간에서 여러 메시지를 한 묶음으로 요청할 때는 I2C_RDWR와 adapter가 지원하는 기능을 확인합니다. SPI 역시 read와 write를 따로 호출할지 SPI_IOC_MESSAGE로 chip select 유지가 필요한 전송을 묶을지 장치 규약에 따라 정합니다.
URB 제출 성공과 전송 완료는 다릅니다
1. 준비
driver가 endpoint, buffer, 길이, completion callback과 context를 준비합니다. callback이 사용할 driver 객체도 살아 있어야 합니다.
2. 제출
usb_submit_urb()가 성공하면 전송이 접수된 것입니다. 요청한 모든 바이트가 장치에 도착했다는 뜻은 아닙니다. 제출 실패 경로도 따로 처리해야 합니다.
3. 완료 callback
상태와 실제 전송 길이를 확인합니다. 취소·disconnect·오류 완료를 정상 데이터와 구분합니다. USB completion callback에서는 잠들 수 없습니다. 오래 걸리거나 sleep이 필요한 처리는 적절한 별도 문맥으로 넘겨야 합니다.
4. 재사용 또는 종료
사용 중인 URB·buffer를 무조건 해제하지 않습니다. disconnect에서 진행 중 전송과 callback을 정리한 뒤 마지막 참조를 반환해야 합니다.
단계는 요청 객체의 수명입니다. USB host가 URB라는 C 구조체 자체를 장치 firmware에 그대로 전송하는 것은 아닙니다.
MMIO·DMA·MSI는 다른 통로입니다
CPU는 BAR를 통해 장치 register에 접근하고, 장치는 DMA 주소를 사용해 RAM의 buffer에 접근할 수 있습니다. MSI/MSI-X는 장치가 interrupt를 알리는 방식입니다. MMIO register에 값을 썼다고 DMA가 끝났거나 해당 interrupt의 처리가 완료된 것은 아닙니다.
| 행동 | 필요한 확인 |
|---|---|
| BAR 접근 | 자원 예약·mapping·접근 폭·endianness·ordering을 맞춥니다. |
| DMA 시작 | DMA mask·mapping·descriptor·완료·unmap 수명을 맞춥니다. |
| interrupt 처리 | 할당한 vector와 장치 상태를 맞추고 mask·ack 규칙을 지킵니다. |
| 장치 제거 | 새 요청을 막고 진행 중 DMA·IRQ·work를 정리한 뒤 자원을 반환합니다. |