이번 시간에는 지난 시간에 이어 NVIDIA Jetson Orin Nano Developer Kit를 해부(3번째 시간)해 보고, 느낀 점을 독자 여러분과 공유해 보고자 한다. 😎
The 3rd time 🚀🚀🚀
목차
6. Jetson Kit Device Tree Overview
7. GPIO and DTB Overlay
8. I2C and SPI Device Tree and Device Drivers
9. CSI Camera and Others
10. Jetson AI - LLM 돌려 보기
References
Jetson Orin Nano Dev Kit은 다양한 주변 장치를 제공하고 있다. 따라서 이번 posting을 통해 어떠한 주변 장치가 있는지, 그리고 해당 주변 장치를 어떻게 제어할 수 있는지 최대한 확인해 보도록 하자. 😌
6. Jetson Kit Device Tree Overview
이번 장에서는Jetson Linux BSP 관련 내용 중, Device Tree와 Device Driver에 관한 내용을 살펴 보고자 한다. Jetson Orin Nano Dev Kit는 아주 다양한 주변 장치를 제공하고 있다. 따라서 이번 posting(혹은 다음 posting)에서는 아주 간단한 수준일지라도 최대한 많은 종류의 device를 사용하고 넘어가기로 하자. 💪
이번 장에서 소개하는 내용은 아래 jetson 공식 document site로 부터 많은 영감(?)을 받아 작성하였다.
6.1 Device Tree 분석
먼저, Jetson Orin Nano Dev Kit를 위한 device tree 파일은 아래 위치에 정의되어 있다.
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public (bottom layer)
-rw-rw-r-- 1 chyi chyi 3318 6월 18 14:48 tegra234-p3701-0000.dtsi
-rw-rw-r-- 1 chyi chyi 2086 6월 18 14:48 tegra234-p3701-0008.dtsi
-rw-rw-r-- 1 chyi chyi 636 6월 18 14:48 tegra234-p3701.dtsi
-rw-rw-r-- 1 chyi chyi 10468 6월 18 14:48 tegra234-p3737-0000+p3701-0000.dts
-rw-rw-r-- 1 chyi chyi 1645 6월 18 14:48 tegra234-p3737-0000.dtsi
-rw-rw-r-- 1 chyi chyi 6517 6월 18 14:48 tegra234-p3740-0002+p3701-0008.dts
-rw-rw-r-- 1 chyi chyi 4407 6월 18 14:48 tegra234-p3740-0002.dtsi
-rw-rw-r-- 1 chyi chyi 5611 6월 18 14:48 tegra234-p3767.dtsi
-rw-rw-r-- 1 chyi chyi 2272 6월 18 14:48 tegra234-p3768-0000+p3767-0000.dts
-rw-rw-r-- 1 chyi chyi 883 6월 18 14:48 tegra234-p3768-0000+p3767-0005.dts
-rw-rw-r-- 1 chyi chyi 4691 6월 18 14:48 tegra234-p3768-0000.dtsi
-rw-rw-r-- 1 chyi chyi 161432 6월 18 14:48 tegra234.dtsi
___________________________________________________
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform (top layer)
-rw-r--r-- 1 chyi chyi 11930 1월 8 10:10 tegra234-camera-p3785.dtsi
-rw-r--r-- 1 chyi chyi 27005 1월 8 10:10 tegra234-dcb-p3737-0000-p3701-0000.dtsi
-rw-r--r-- 1 chyi chyi 6403 1월 8 10:10 tegra234-p3701-0000-prod-overlay.dtsi
-rw-r--r-- 1 chyi chyi 2299 1월 8 10:10 tegra234-p3701-0000.dtsi
-rw-r--r-- 1 chyi chyi 478 1월 8 10:10 tegra234-p3701-0005.dtsi
-rw-r--r-- 1 chyi chyi 2912 1월 8 10:10 tegra234-p3701-0008.dtsi
-rw-r--r-- 1 chyi chyi 294 1월 8 10:10 tegra234-p3737-0000+p3701-0000-nv.dts
-rw-r--r-- 1 chyi chyi 302 1월 8 10:10 tegra234-p3737-0000+p3701-0004-nv.dts
-rw-r--r-- 1 chyi chyi 302 1월 8 10:10 tegra234-p3737-0000+p3701-0005-nv.dts
-rw-r--r-- 1 chyi chyi 302 1월 8 10:10 tegra234-p3737-0000+p3701-0008-nv.dts
-rw-r--r-- 1 chyi chyi 4444 1월 8 10:10 tegra234-p3737-0000+p3701-xxxx-nv-common.dtsi
-rw-r--r-- 1 chyi chyi 3509 1월 8 10:10 tegra234-p3737-0000.dtsi
-rw-r--r-- 1 chyi chyi 5589 1월 8 10:10 tegra234-p3740-0002+p3701-0008-nv-common.dtsi
-rw-r--r-- 1 chyi chyi 312 1월 8 10:10 tegra234-p3740-0002+p3701-0008-nv-safety.dts
-rw-r--r-- 1 chyi chyi 258 1월 8 10:10 tegra234-p3740-0002+p3701-0008-nv.dts
-rw-r--r-- 1 chyi chyi 5177 1월 8 10:10 tegra234-p3740-0002+p3701-0008-safety.dtsi
-rw-r--r-- 1 chyi chyi 6418 1월 8 10:10 tegra234-p3740-0002.dtsi
-rw-r--r-- 1 chyi chyi 2133 1월 8 10:10 tegra234-p3767-0000.dtsi
-rw-r--r-- 1 chyi chyi 501 1월 8 10:10 tegra234-p3768-0000+p3767-0000-nv-px1.dts
-rw-r--r-- 1 chyi chyi 375 1월 8 10:10 tegra234-p3768-0000+p3767-0000-nv-super.dts
-rw-r--r-- 1 chyi chyi 248 1월 8 10:10 tegra234-p3768-0000+p3767-0000-nv-taylor-high.dts
-rw-r--r-- 1 chyi chyi 246 1월 8 10:10 tegra234-p3768-0000+p3767-0000-nv-taylor-low.dts
-rw-r--r-- 1 chyi chyi 258 1월 8 10:10 tegra234-p3768-0000+p3767-0000-nv.dts
-rw-r--r-- 1 chyi chyi 375 1월 8 10:10 tegra234-p3768-0000+p3767-0001-nv-super.dts
-rw-r--r-- 1 chyi chyi 266 1월 8 10:10 tegra234-p3768-0000+p3767-0001-nv.dts
-rw-r--r-- 1 chyi chyi 537 1월 8 10:10 tegra234-p3768-0000+p3767-0003-nv-super.dts
-rw-r--r-- 1 chyi chyi 468 1월 8 10:10 tegra234-p3768-0000+p3767-0003-nv.dts
-rw-r--r-- 1 chyi chyi 537 1월 8 10:10 tegra234-p3768-0000+p3767-0004-nv-super.dts
-rw-r--r-- 1 chyi chyi 468 1월 8 10:10 tegra234-p3768-0000+p3767-0004-nv.dts
-rw-r--r-- 1 chyi chyi 537 1월 8 10:10 tegra234-p3768-0000+p3767-0005-nv-super.dts
-rw-r--r-- 1 chyi chyi 460 1월 8 10:10 tegra234-p3768-0000+p3767-0005-nv.dts
-rw-r--r-- 1 chyi chyi 7204 1월 8 10:10 tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi
-rw-r--r-- 1 chyi chyi 847 1월 8 10:10 tegra234-p3768-0000.dtsi
📌 tegra234는 soc 명칭을, p3767은 som part number를, 그리고 p3768은 carrier board part number를 칭한다.
___________________________________________________
<Jetson Orin Nano Dev Kit device tree 계층 구조>
위의 많은 dts/dtsi 파일 중에서 Jetson Orin Nano Dev Kit 관련 부분만을 계층 구조로 정리해 보면 다음과 같다.
tegra234.dtsi
(SoC)
^
|
tegra234-p3767.dtsi
(SOM)
tegra234-p3768-0000.dtsi
(Carrier board)
^
|
tegra234-p3768-0000+p3767-0005.dts
(jetson orin nano dev kit) <- bottom layer
tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi
^
|
tegra234-p3768-0000+p3767-0005-nv.dts
(nv-public/nv-platform) <- top layer
위의 device tree 계층 구조를 구성하는 주요 파일(dtsi/dts)을 하나씩 나열해 보았다.
[그림 6.6] NVIDIA Jetson Orin Nano Dev Kit에 대한 device tree - tegra234-p3768-0000+p3767-0005.dts
[그림 6.7] nv-platform/tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi
[그림 6.8] nv-platform/tegra234-p3768-0000+p3767-0005-nv.dts
6.2 Tegra234 GPIO 해부
Tegra234 SoC에는 2개의 GPIO controller chip(gpiochip0: main gpio, gpiochip1: aon gpio)이 내장되어 있다. 이 중 gpiochip0(Main GPIO chip)은 24개의 bank(GPIO_PORT_A ~ Z, GPIO_PORT_AC ~ AG)로 구성되어 있고, gpiochip1(AON GPIO chip)은 6개의 bank(GPIO_PORT_AA ~ GG)로 구성되어 있다. 이는 gpiodetect 명령과 gpioinfo 명령을 통해서도 확인 가능하다.
...
[그림 6.9] gpiodetect and gpioinfo 명령 실행 모습
📌 gpiochip0은 164개의 gpio line이 있고, gpiochip1은 32개의 line이 있다.
📌 한편, gpioinfo, gpiodetect 명령 등을 포함한 libgpiod 관련 자세한 사항은 아래 문서를 참조하기 바란다.
한편, 아래 table은 gpiochip0의 bank(port) 정보, bank 당 pin의 갯수, 그리고 누적 핀의 갯수(offset) 정보를 보여준다.
[그림 6.10] gpiochip0(main gpio chip) port 구성 정보 [출처 - 참고문헌 3]
위의 내용에도 나와 있듯이, 보통은 각 bank(or port)당 8개의 gpio line이 존재할 것 같지만, 실제로는 그렇지 않은 것들도 보인다. 따라서 아래의 공식에 의해 각각 최대 192와 48개의 gpio line이 있어야 하지만, 실제로는 앞서 확인해 본 바와 같이 164개와 32개의 line만 존재하게 된다.
gpiochip0 : 24 bank(= port) x 8 = 192 lines
gpiochip1 : 6 bank(= port) x = 48 lines
따라서, 실제 gpio line 번호를 계산하는 것도 약간은 불편해 보인다. 가령 이전 posting에서 다루었던 J14 header pin 10(Force Recovery)의 경우는 아래와 같이 line 35(PG.00 = PORT G 0번 line)에 해당하는데, 이는 위의 table의 Port Offset 내용을 보면 그 이유를 쉽게 알 수가 있다.
line 35: "PG.00" "Force Recovery" input active-low [used]
📌 PORT A (8개) + PORT B (1개) + PORT C (8개) + PORT D (4개) + PORT E (8개) + PORT F (6개) = 35가 된다.
참고로, 아래 내용은 carrier board device tree 내용 중, Force Recovery pin 설정 부분인데, 이를 통해 역으로 GPIO 정보(TEGRA234_MAIN_GPIO(G, 0))를 확인할 수도 있다.
<tegra234-p3768-0000.dtsi 파일 내용>
key-force-recovery {
label = "Force Recovery";
gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>; /* PG.00 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_1>;
};
label = "Force Recovery";
gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>; /* PG.00 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_1>;
};
한편, linux kernel에서는 아래와 같이 PG.00 line을 gpio-383으로 인식하는데, 383은 port offset 35에 gpiochip0 base index 값(= 348)을 더한 결과이다. 즉, 348 + 35 + 0 = 383.
📌 tegra234-gpio(gpiochip0)의 base index 348이고, tegra234-gpio-aon(gpiochip1) 316을 사용한다.
따라서 kernel에서 인식하는 gpio number는 아래의 공식을 기반으로 한다고 이해하면 된다.
base index + port_offset + pin_offset
지금까지 Jetson Orin Nano Dev Kit의 GPIO 구성에 대한 내용을 대략적으로 살펴 보았다. 이제부터는 간단한 GPIO 테스트를 진행해 보기로 하자.
<시험 내용>
gpio-383(Factory Recovery pin)에 아래와 같은 GPIO 설정 시험을 진행해 보고 싶다.
Hi(default state) -> Lo(0 설정) -> Hi(1 설정)
<시험 방법>
-> libgpiod project에서 제공하는 gpioset 명령을 이용한다.
chyi@jetsonkit:~$ gpioset 0 35=0
gpioset: error setting the GPIO line values: Device or resource busy
chyi@jetsonkit:~$ gpioset 0 35=1
gpioset: error setting the GPIO line values: Device or resource busy
gpioset: error setting the GPIO line values: Device or resource busy
chyi@jetsonkit:~$ gpioset 0 35=1
gpioset: error setting the GPIO line values: Device or resource busy
어라, 그런데 어찌된 일인지 명령이 안먹힌다. 💤 왜 그럴까 ?
(다른 숨겨진 이유가 있을 수도 있으니) 그렇다면, 다른 GPIO port에 대해 동일한 시험을 해보면 어떨까 ? 아래 그림은 J12 40 pin 확장 헤더를 나타내는데, 이 중 7번 pin(GPIO09)를 대상으로 동일한 시험을 진행해 보기로 하자.
[그림 6.12] J12 40-pin 확장 헤더 [출처 - 참고문헌 5]
그런데, 7번 pin은 Raspberry Pi 확장 헤더와 비슷한 개념으로 정의된 번호이며, GPIO09는 Orin module의 pin name으로 보인다. 그렇다면, 우리에게 실제로 필요한 정보인 SoC내의 GPIO port number는 어떻게 알 수가 있을까 ?
(결론 부터 얘기하면) 이를 위해 [참고문헌 5]에서 아래 테이블을 찾았는데, 아래 내용을 보면 위의 7번 pin에 해당하는 SoC GPIO Port#는 GPIO PAC.06임을 알 수가 있다(결국 문서를 들여다 보아야 한다는 얘기다). 🔍
[그림 6.13] J12 확장 핀 - pin 7 (GPIO) [출처 - 참고문헌 5]
한편 GPIO PAC.06은 gpioinfo 명령으로 확인한 결과, line 144(port offset)에 해당하는 것을 알 수 있다.
line 144: "PAC.06" unused input active-high
<GPIO Pin number 추론(?) 과정>
J12 40핀 확장 헤더 7번 pin -> GPIO09(Orin Module pin name) -> GPIO PAC.06 (SoC GPIO port) -> 144 (port offset)
따라서, 아래와 같이 gpioset 명령으로 gpio 설정 변경을 시도해 보면 된다.
chyi@jetsonkit:~$ gpioset --mode=wait $(gpiofind "PAC.06")=1
chyi@jetsonkit:~$ gpioget 0 144
0
0
chyi@jetsonkit:~$ gpioset --mode=wait $(gpiofind "PAC.06")=0
gpioget: invalid GPIO offset: 144=0
chyi@jetsonkit:~$ gpioget 0 144
0
0
하지만 gpioset 설정이 여전히 먹히질 않는다. 도대체 뭐가 문제일까 ? gpio mode가 output이 아닌 input으로 표현되는 것도 이상하고 도무지 이해가 안된다. 😈
(내용이 길어지는 관계로) 정답은 다음 장에서 공개하기로 하자. 😋
7. GPIO and DTB Overlay
문제의 원인을 찾던 중, 아래 동영상을 하나 발견했다. 세상에는 참으로 훌륭한 분들이 많이 있는 것 같다. 아래 동영상 파일과 JetsonHacks site의 운영자인 Jim에게 이 자리를 빌어 감사의 마음을 전한다. 👍
I salute you for your efforts.
이번 장에서 소개하는 내용은 위의 동영상과 아래 site의 내용을 기초로 하였다.
7.1 GPIO patch code 실행
먼저, 위의 github에서 code를 내려 받는다.
<Ubuntu 22.04 LTS desktop>
-> 물론 아래 작업을 target board에서 직접 수행해도 된다.
$ git clone https://github.com/jetsonhacks/jetson-orin-gpio-patch
$ cd jetson-orin-gpio-patch
$ dtc -O dtb -o pin7_as_gpio.dtbo pin7_as_gpio.dts
-> pin7_as_gpio.dtbo 파일을 target board /boot 디렉토리로 복사하자.
<Target board>
chyi@jetsonkit:~$ sudo cp pin7_as_gpio.dtbo /boot
chyi@jetsonkit:~$ sudo /opt/nvidia/jetson-io/jetson-io.py
-> Jetson Dev Kit에서 제공하는 위 명령을 사용하여 device tree overlay 설정을 추가하도록 한다.
[그림 7.1] jetson-io.py 명령 실행 (1)
이어서, 새로 추가된 Pin 7 gpio bidirectional 메뉴를 선택한다.
[그림 7.2] jetson-io.py 명령 실행 (2)
이후, /boot/extlinux/extlinux.conf 파일이 자동 수정되었다는 문구가 출력된다.
(나중에) 위에서 자동으로 수정된 extlinux.conf 파일의 내용을 확인해 보니, 후반부에 아래의 내용이 추가되어 있음을 알 수 있다.
참고로, extlinux.conf 파일의 전체 내용은 다음과 같다.
_____________________________________________________________
LABEL primary
MENU LABEL primary kernel
LINUX /boot/Image
INITRD /boot/initrd
APPEND ${cbootargs} root=PARTUUID=757cb550-ca70-4888-993d-ff7fddaa1de6 rw
rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 firmware_classs
.path=/etc/firmware fbcon=map:0 nospectre_bhb video=efifb:off console=tty0
MENU LABEL primary kernel
LINUX /boot/Image
INITRD /boot/initrd
APPEND ${cbootargs} root=PARTUUID=757cb550-ca70-4888-993d-ff7fddaa1de6 rw
rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 firmware_classs
.path=/etc/firmware fbcon=map:0 nospectre_bhb video=efifb:off console=tty0
LABEL JetsonIO
MENU LABEL Custom Header Config: <HDR40 Pin 7 gpio bidirectional>
LINUX /boot/Image
FDT /boot/dtb/kernel_tegra234-p3768-0000+p3767-0005-nv-super.dtb //dtb 적용 대상 지정
INITRD /boot/initrd
APPEND ${cbootargs} root=PARTUUID=757cb550-ca70-4888-993d-ff7fddaa1de6 rr
w rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 firmware_claa
ss.path=/etc/firmware fbcon=map:0 nospectre_bhb video=efifb:off console=tty0
OVERLAYS /boot/pin7_as_gpio.dtbo //새로 추가한 dtb overlay 파일 지정
MENU LABEL Custom Header Config: <HDR40 Pin 7 gpio bidirectional>
LINUX /boot/Image
FDT /boot/dtb/kernel_tegra234-p3768-0000+p3767-0005-nv-super.dtb //dtb 적용 대상 지정
INITRD /boot/initrd
APPEND ${cbootargs} root=PARTUUID=757cb550-ca70-4888-993d-ff7fddaa1de6 rr
w rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 firmware_claa
ss.path=/etc/firmware fbcon=map:0 nospectre_bhb video=efifb:off console=tty0
OVERLAYS /boot/pin7_as_gpio.dtbo //새로 추가한 dtb overlay 파일 지정
_____________________________________________________________
📌 위의 내용대로라면, kernel_tegra234-p3768-0000+p3767-0005-nv-super.dtb 파일이 적용되고, 이어 pin7_as_gpio.dtbo에 정의한 기능이 그 위에 override 된다.
📌 주의: kernel_tegra234-p3768-0000+p3767-0005-nv-super.dtb 파일은 /boot가 아니라 /boot/dtb 디렉토리 아래에 있다.
이후, target board를 재부팅하면, 아래와 같은 booting option이 출력되고, 1을 선택하면, 새로 추가한 DTB overlay 설정이 적용된다.
LT4 boot options
0: primary kernel
1: Custom Header Config: <HDR40 Pin 7 gpio bidrectional>
Press 0-1 to boot selection within 3.0 seconds.
Press any other key to boot default (Option: 1)
그런데, Taget board 재부팅 후, GPIO line 144(GPIO PAC.06) 상태를 확인한 결과는 기존과 다르지 않다. 즉, 아무런 변경 없이, 기존과 동일하게 Input mode로 표시된다.
$ gpioinfo gpiochip0
이 상태에서 examples/simple_out.py code를 실행한 후, GPIO 144 line의 결과를 확인해 보면, 이전과는 확연히 달라진 결과를 마주하게 된다. 😋
<Prerequisites>
$ sudo apt update
$ sudo apt install python3 python3-pip -y
$ sudo pip install --upgrade Jetson.GPIO
-> 아래 python code를 실행하기 전에 Jetson.GPIO package를 미리 설치해 주어야 한다.
$ sudo usermod -a -G gpio $USER
-> gpio group에 자신의 계정을 추가한다(이유: 이후 실행하는 python code를 root로 실행하지 않게 하기 위함).
-> 이후 logout -> login을 하거나, reboot을 해 주어야 위의 내용이 반영된다.
$ cd examples
$ python3 ./simple_out.py
-> 7번 pin을 output mode로 설정하고, gpio value를 1 -> 0 -> 1 -> 0으로 반복 설정하는 간단한 코드이다.
$ gpioinfo gpiochip0
-> gpio mode가 Output으로 바뀌어 있으며, 이제는 Jetson-gpio(used)로 표시된다.
7.2 GPIO patch code 분석
그럼, 도대체 어떻게 해서, 위와 같이 정상 동작하게 된 것일까 ? 해답은 아래에 보이는 dts overlay file을 새로 추가했기 때문이다.
[그림 7.9] 새로 추가된 dts overlay file - pin7_as_gpio_dts 파일
참고로, 아래 내용은 target board 상에서 fdtdump 명령으로 pin7_as_gpio.dtbo binary 내용을 확인해 본 것이다.
$ fdtdump /boot/pin7_as_gpio.dtbo
[그림 7.10] fdtdump /boot/pin7_as_gpio.dtbo 결과
📌 fdtdump 명령을 기억해 두면 나중에 유용하게 사용할 수가 있다.
문법이 다소 복잡해 보이는데, 위의 overlay file이 어떤 원리로 만들어지는 지를 따져보기 위해, 이것 저것 파일을 찾다 보니, 아래 file이 눈에 들어 온다. 이 파일은 40 pin header의 설정을 overlay 형식으로 정의한 것으로 보이는데, 이 내용 중에는 7번 pin에 대한 내용도 담겨 있다.
source/hardware/nvidia/t23x/nv-public/overlay/tegra234-p3767-0000-common-hdr40.dtsi
[그림 7.11] tegra234-p3767-0000-common-hdr40.dtsi 파일 - overlay 파일
내용을 좀 더 파악해 보니, 위의 dts 파일은 Jetson Orin Nano Dev Kit에서 현재 사용되지 않는 것 같다. 따라서 위의 내용을 참조하여 새로운 overlay 파일을 하나 만들어 추가하면 되는데, 그 내용이 앞서 소개한 pin7_as_gpio.dts 파일로 이해하면 된다. 😋
hdr40-pin7 { //현재는 audio codec용으로 설정되어 있음.
nvidia,pins = "soc_gpio59_pac6";
nvidia,function = "aud"; //audio
nvidia,pin-label = "aud_mclk"; //audio codec master clock
nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>;
};
=>
jetson_io_pinmux: exp-header-pinmux {
hdr40-pin7 {
nvidia,pins = "soc_gpio59_pac6";
nvidia,tristate = <0x0>;
nvidia,enable-input = <0x1>;
nvidia,pull = <0x0>;
};
(device tree overlay 내용을 살펴 보았으니) 다음으로, simple_out.py 파일의 내용을 분석해 보기로 하자.
simple_out.py code가 제대로 동작하기 위해서는, 사전에 아래 jetson-gpio package를 설치해야만 한다(앞서 이미 설치하였음).
<simple_out.py 코드에서 수행하는 내용>
1) gpio pin 지정(7번) ............................................................ (A)
2) output mode로 지정
3) 초기 값 (= HIGH) 지정
4) while loop를 도면서 1초 간격으로 curr_value 값 출력(curr_value는 매 loop 마다 toggle 됨).
그렇다면, 앞서 표시해 두었던 (A) 부분은 내부적으로 어떻게 처리되는 것일까 ? 답은 아주 간단하다. 우리는 이미 6장에서 GPIO Pin number 추론(?) 과정을 살펴 본 바가 있다. 즉, 다음과 같이 말이다.
J12 40핀 확장 헤더 7번 pin -> GPIO90(Orin Module pin name) -> GPIO PAC.06(SoC GPIO port) -> 144 (port offset)
jetson-gpio package 내에 포함된 python code(gpio_pin_data.py)를 보면, 위의 개념을 반영하기 위해 아래와 같은 tuple 정보를 담은 list가 정의되어 있음을 알 수가 있다. 이쯤되면, 나머지 과정은 따로 설명하지 않아도 무슨 말인지 금방 이해가 가리라고 본다. 😋
(144, 'PAC.06', "tegra234-gpio", 7, 4, 'GPIO09', 'GP167', None, None)
7.3 Kernel patch 적용
이번 장에서 끝으로 소개할 내용은 pinmux code에 대한 kernel patch 부분이 되겠다. Patch할 파일은 아래 2개의 파일이다.
drivers/pinctrl/tegra/pinctrl-tegra.c
drivers/pinctrl/tegra/pinctrl-tegra.h
📌 tegra soc의 pinmux 설정 관련 드라이버 코드다.
<Patch를 하는 이유>
이 패치는 Tegra pinctrl 드라이버의 GPIO 핀 다중화 처리 능력을 다음과 같이 향상시켜준다.
1) 원래 핀 상태 유지하기: 이전에는 GPIO를 요청하면 sfsel 비트가 지워졌고(GPIO 모드 강제), 해제되면 항상 설정되었다(특수 기능 모드 강제). 이제 드라이버는 원래 상태를 기억하고 GPIO가 해제되면 복원한다.
2) 구성 추적 추가: pingroup_configs 배열은 그룹별 상태를 저장하는 메커니즘을 도입하여 향후 향상을 위해 드라이버를 더욱 유연하게 만든다.
3) 불필요한 변경 방지: sfsel 비트의 조건부 복원은 불필요한 레지스터 쓰기를 방지하여 효율성을 높이고 부작용을 줄인다.
1) 원래 핀 상태 유지하기: 이전에는 GPIO를 요청하면 sfsel 비트가 지워졌고(GPIO 모드 강제), 해제되면 항상 설정되었다(특수 기능 모드 강제). 이제 드라이버는 원래 상태를 기억하고 GPIO가 해제되면 복원한다.
2) 구성 추적 추가: pingroup_configs 배열은 그룹별 상태를 저장하는 메커니즘을 도입하여 향후 향상을 위해 드라이버를 더욱 유연하게 만든다.
3) 불필요한 변경 방지: sfsel 비트의 조건부 복원은 불필요한 레지스터 쓰기를 방지하여 효율성을 높이고 부작용을 줄인다.
_______________________________________________________________
<Patch 방법>
$ cp pinctrl-tegra-sfsel.patch <your_path>/Linux_for_Tegra/source/kernel/kernel-jammy-src
$ cd Linux_for_Tegra/source/kernel/kernel-jammy-src
$ patch -p1 < ./pinctrl-tegra-sfsel.patch
patching file drivers/pinctrl/tegra/pinctrl-tegra.c
patching file drivers/pinctrl/tegra/pinctrl-tegra.h
<Kernel build 하기>
$ export ARCH=arm64
$ export CROSS_COMPILE=/mnt/hdd/workspace/nvidia/jetson/toolchain/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu-
$ export INSTALL_MOD_PATH=/mnt/hdd/workspace/nvidia/jetson/06222025/Manual/Linux_for_Tegra/rootfs
$ export KERNEL_HEADERS=/mnt/hdd/workspace/nvidia/jetson/06222025/Manual/Linux_for_Tegra/source/kernel/kernel-jammy-src
-> kernel build에 필요한 몇가지 환경 설정을 한다(자신의 환경에 맞게 적절히 조절한다).
$ cd Linux_for_Tegra/source/
$ make -C kernel
$ sudo -E make install -C kernel
$ cp kernel/kernel-jammy-src/arch/arm64/boot/Image ../kernel/Image
(반복되는 부분이므로) 나머지 과정(Image -> /boot 디렉토리 복사)은 이전 posting을 참고하도록 하자.
이상으로 BSP work 중에서 가장 기초적인 내용이라고 할 수 있는 GPIO에 관하여 2개의 장(6, 7장)에 걸쳐서 나름 상세히 파악해 보았다. GPIO가 아무리 기초적인 내용이라고 할지라도, 결코 쉽게 무시하고 넘어갈 수 있는 부분이 아니라는 점을 강조하고 싶다. 💢
8. I2C and SPI Device Tree and Device Drivers
이번 장에서는 i2c 및 SPI 장치를 각각 하나씩 장착하고, 이를 인식하는 과정을 소개해 보고자 한다.
내용이 길어지는 관계로, 나머지 내용은 다음 posting을 통해 확인하기로 하자. Bye~ 😎
To be continued...
May the source be with you~
References
[1] jetson-orin-datasheet-nano-developer-kit-3475392-r2.pdf
-> 제품 brochure
[2] https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-orin/nano-super-developer-kit/
-> Jetson Orin Nano Super Developer Kit 공식 site
[3] https://docs.nvidia.com/jetson/archives/r36.4.3/DeveloperGuide/
-> NVIDIA Jetson Linux developer guide 문서 *****
[4] https://www.jetson-ai-lab.com/initial_setup_jon.html
-> Initial setup guide for etson Orin Nano Developer Kit *****
[5] Jetson Orin Nano Developer Kit Carrier Board, SP-11324-001_v1.3 pdf
[6] Jetson Orin NX Series and Jetson Orin Nano Series Product Design Guide
[7] Jetson Orin NX Series and Jetson Orin Nano Series Pin and Function Names Guide
[8] NVIDIA Orin Series System-on-Chip Technical Reference Manual
[9] NVIDIA Jetson Orin Nano Series Modules Data Sheet - Ampere GPU + Arm Cortex-A78AE CPU + LPDDR5
-> Jetson Orin Nano Developer Kit 관련 h/w 문서
[10] https://docs.nvidia.com/jetson/archives/r35.4.1/DeveloperGuide/text/AR/BootArchitecture/JetsonOrinSeriesBootFlow.html
-> Jetson Orin Nano Boot Flow
[11] https://www.jetson-ai-lab.com/index.html
[12] https://www.jetson-ai-lab.com/initial_setup_jon.html
[13] https://www.jetson-ai-lab.com/tutorial-intro.html
-> ai-lab & Initial setup guide
[14] https://docs.nvidia.com/deeplearning/tensorrt/latest/getting-started/quick-start-guide.html
-> TensorRT guide
[15] CUDA C++ Programming Guide, Release 12.9, NVIDIA Corportation
[16] https://developer.ridgerun.com/wiki/index.php/Yocto_Support_for_NVIDIA_Jetson_Platforms_-_Setting_up_Yocto
[17] https://github.com/OE4T/tegra-demo-distro#tegra-demo-distro
[18] https://jetsonhacks.com/
[19] https://github.com/jetsonhacks
[20] https://jetsonhacks.com/2025/03/13/build-jetson-orin-kernel-and-modules/
[21] https://jetsonhacks.com/2025/04/07/device-tree-overlays-on-jetson-scary-but-fun/
-> Cool site~
[22] https://developer.ridgerun.com/wiki/index.php/NVIDIA_Jetson_-_Device_Tree_Overlay
[23] https://github.com/TechNexion-Vision/TEV-JetsonOrin-Nano_device-tree
[24] https://echomav.github.io/docs/latest/echopilot_ai/
[25] https://developer.nvidia.com/embedded/develop/software
[26] https://nvidia-jetson.piveral.com/jetson-orin-nano/configuring-gpio-output-on-nvidia-jetson-orin-nano/
-> gpio configurations
[27] Jetson_Orin_NX_Orin_Nano_Pin_Descriptiosn.xlsx
->Jetson Orin Nano pin description 엑셀 문서
[28] https://bootlin.com/blog/enabling-new-hardware-on-raspberry-pi-with-device-tree-overlays/
[29] https://wikidocs.net/3205
-> device tree overlay
[30] https://jetsonhacks.com/nvidia-jetson-orin-nano-gpio-header-pinout/
[31] And, Google & Gemini~
Slowboot