관련자료
- 제품정보: https://www.hardkernel.com/shop/odroid-n2-with-4gbyte-ram-2 (CPU: S922X, CPU: Mali-G52)
- u-boot 업데이트: https://u-boot.readthedocs.io/en/latest/board/amlogic/odroid-n2.html (v2021기준 부트 파티션 시작위치가 1M일경우 부트로더가 파티션 영역을 초과, 2M 정도로 넉넉하게 배치할 필요가 있음)
- linux-meson wiki: https://linux-meson.com (meson 계열 프로세서 요약과 커널 적용내역을 확인하기 쉬움)
- ODROID 정보 및 Prebuild OS: https://docs.linuxfactory.or.kr
- GPIO PIN MAP: https://wiki.odroid.com/odroid-n2/hardware/expansion_connectors
- Ubuntu 20.10 업데이트: https://forum.odroid.com/viewtopic.php?f=52&t=40761
Vanilla 커널사용 시 필요한 패치(5.10, 5.12버전 기준)
- 재부팅 문제 수정 (참고 소스)
drivers/gpu/drm/meson/meson-drv.c 파일의 platform_driver 구조체 변수 선언에서 shutdown 함수 할당 주석 또는 제거 (적용 후에도 간혹 재부팅 안되는 경우가 있음, 5.10버전대는 meson_drv.c 파일)
static struct platform_driver meson_drm_platform_driver = {
.probe = meson_drv_probe,
/* .shutdown = meson_drv_shutdown, */
.driver = {
.name = "meson-drm",
.of_match_table = dt_match,
.pm = &meson_drv_pm_ops,
},
};
- PWM-GPIO 추가 (PWM-FAN을 사용할 경우)
https://github.com/tobetter/linux에서 drivers/pwm/pwm-gpio.c 파일을 추가
- Makefile(drivers/pwm) 적용
...
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
obj-$(CONFIG_PWM_GPIO) += pwm-gpio.o
obj-$(CONFIG_PWM_HIBVT) += pwm-hibvt.o
obj-$(CONFIG_PWM_IMG) += pwm-img.o
...
- Kconfig(drivers/pwm) 적용
...
To compile this driver as a module, choose M here: the module
will be called pwm-fsl-ftm.
config PWM_GPIO
tristate "Generic GPIO bit-banged PWM driver"
depends on OF
depends on GPIOLIB
help
Some platforms do not offer any hardware PWM capabilities but do have
General Purpose Input Output (GPIO) pins available. Using the kernels
High-Resolution Timer API this driver tries to toggle GPIO using the
generic kernel PWM framework. The maximum frequency and/or accuracy
is dependent on several factors such as system load and the maximum
speed a pin can be toggled at the hardware.
To compile this driver as a module, choose M here: the module
will be called pwm-gpio.
config PWM_HIBVT
tristate "HiSilicon BVT PWM support"
depends on ARCH_HISI || COMPILE_TEST
depends on HAS_IOMEM
...
- Device Tree 적용
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
...
#include <dt-bindings/sound/meson-g12a-toacodec.h>
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
#include <dt-bindings/pwm/pwm.h>
...
/ {
...
pwmgpio:pwmgpio {
compatible = "pwm-gpio";
#pwm-cells = <3>;
pwm-gpios = <&gpio_ao GPIOAO_10 GPIO_ACTIVE_HIGH>;
status = "okay";
};
pwmfan:pwm-fan {
compatible = "pwm-fan";
pwms = <&pwmgpio 0 40000 PWM_POLARITY_INVERTED>;
cooling-min-state = <0>;
cooling-max-state = <3>;
#cooling-cells = <2>;
cooling-levels = <0 120 170 220>;
};
};
&cpu_thermal {
trips {
fan_0: trip-point@4 {
temperature = <45000>;
hysteresis = <5000>;
type = "active";
};
fan_1: trip-point@5 {
temperature = <65000>;
hysteresis = <5000>;
type = "active";
};
fan_2: trip-point@6 {
temperature = <75000>;
hysteresis = <5000>;
type = "active";
};
};
cooling-maps {
fan_cooling_map0 {
trip = <&fan_0>;
cooling-device = <&pwmfan 0 1>;
};
fan_cooling_map1 {
trip = <&fan_1>;
cooling-device = <&pwmfan 1 2>;
};
fan_cooling_map2 {
trip = <&fan_2>;
cooling-device = <&pwmfan 2 3>;
};
};
};
...
- GPIOMEM 추가 (GPIOMEM을 사용할 경우)
https://github.com/hardkernel/linux에서 drivers/char/aml-gpiomem.c 파일을 추가
- Makefile(drivers/char) 적용
...
obj-$(CONFIG_XILLYBUS) += xillybus/
obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
obj-$(CONFIG_ADI) += adi.o
obj-$(CONFIG_AMLOGIC_GPIOMEM) += aml-gpiomem.o
- Kconfig(drivers/char) 적용
...
and SSM (Silicon Secured Memory). Intended consumers of this
driver include crash and makedumpfile.
config AMLOGIC_GPIOMEM
tristate "/dev/gpiomem rootless GPIO access via mmap() on the Amlogic"
default m
help
Provides users with root-free access to the GPIO registers
on Meson g12 platform. Calling mmap(/dev/gpiomem) will map the GPIO
register page to the user's pointer. This drvier can allow to access
gpio memory area in user account.
endmenu
...
- Device Tree 적용
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
(compatible 문자열에 공백을 제거하고싶다면 drivers/char/aml-gpiomem.c의 compatible 정의도 마찬가지로 공백을 제거해야 함)
/ {
...
gpiomem {
compatible = "amlogic, gpiomem";
reg = <0x0 0xff634000 0x0 0x1000>;
status = "okay";
};
};
- I2C-0 활성
- Device Tree 적용
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
pinctrl 이름은 drivers/pinctrl/meson/pinctrl-meson-g12a.c 파일에서 참조
GPIO PINMAP은 하드커널 위키에서 참조
/ {
...
};
&i2c2 {
status = "okay";
pinctrl-0 = <&i2c2_sda_x_pins>, <&i2c2_sck_x_pins>;
pinctrl-names = "default";
};
...
- I2C-1 활성
- Device Tree 적용
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
/ {
...
};
&i2c3 {
status = "okay";
pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
pinctrl-names = "default";
/* rtc를 사용할 때 아래 블록 함께 추가 */
pcf8563: rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
};
};
...
- SPIDEV0.0 활성
- Device Tree 적용
/ {
...
};
&spicc0 {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&spicc0_x_pins &spicc0_ss0_x_pins>;
cs-gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>;
spidev: spidev@0 {
status = "okay";
compatible = "linux,spidev";
reg = <0>;
/* spi default max clock 100Mhz */
spi-max-frequency = <10000000>;
};
};
...
- GPIO PWM CD, EF 채널 추가
- Device Tree 적용 (참고내용)
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi 파일에 아래 내용 추가
sysfs 경로는ls -al /sys/class/pwm/pwmchip*/device
명령을 실행하여 링크가 ffd1a000.pwm면 CE, ffd19000.pwm면 EF 핀의 pwmchip
/ {
...
};
&periphs_pinctrl {
pwmcd_to_gpios: pwmcd_gpio {
mux {
groups = "GPIOX_5", "GPIOX_6";
function = "gpio_periphs";
};
};
pwmef_to_gpios: pwmef_gpio {
mux {
groups = "GPIOX_16", "GPIOX_7";
function = "gpio_periphs";
};
};
};
&pwm_cd {
status = "okay";
clocks = <&xtal>, <&xtal>, <&xtal>, <&xtal>;
clock-names = "clkin0", "clkin1", "clkin2", "clkin3";
pinctrl-names = "default";
pinctrl-0 = <&pwm_c_x5_pins &pwm_d_x6_pins>;
pinctrl-1 = <&pwmcd_to_gpios>;
};
&pwm_ef {
status = "okay";
clocks = <&xtal>, <&xtal>, <&xtal>, <&xtal>;
clock-names = "clkin0", "clkin1", "clkin2", "clkin3";
pinctrl-names = "default";
pinctrl-0 = <&pwm_e_pins &pwm_f_x_pins>;
pinctrl-1 = <&pwmef_to_gpios>;
};
...
해결이 필요한 문제
- Prebuild OS (Ubuntu 10.04)
- PWM-FAN이 45도 이상 온도에서도 동작하지 않음 (원인을 잘 모르겠음)
- btrfs를 사용할 수 없음 (마운트하면 커널 패닉)
- Vanilla Kernel
- sysfs GPIO(/sys/class/gpio)가 동작하지 않음 (대신 hardkernel 커널에 포팅 된 gpiomem을 사용)
- GPU 하드웨어 가속 드라이버(panfrost)가 X11에서 영상 디코딩 레이어, 마우스 포인터 렌더링에 문제가 있음
- 프로세서 로드가 높을 때 IO가 많이 일어나면 커널 패닉이 일어나는 일이 많음
해결이 안될거같은 문제
- SPI 인터페이스와 GPIO 동시 사용 시 SPI에 간섭이 생겨 SPI 데이터가 손상되는 문제 발생
SPI 드라이버가 DMA 방식이 아닌 PIO 모드로 구현된것이 원인일 것으로 예상(참조: spi meson 코드), 라즈베리파이에서는 간섭이 일어나지 않으므로 SPI와 GPIO를 동시에 사용한다면 프로세서의 성능차이가 커도 라즈베리파이를 사용하거나 라즈베리파이 피코, 아두이노같은 장치를 함께 사용해야 하는 단점이 발생 (예로 IR 신호를 송신하면 SPI 디스플레이 화면이 잠깐 일그러지며 SPI 디스플레이에 제어신호 전송 시 SPI 데이터가 손상되면 제어코드가 잘못 전송되어 표현에 문제가 생기는 현상도 발생) - SPI 인터페이스의 데이터 전송속도 문제
- Vanilla Kernel 기준, 약 115kb 전송에 걸리는 시간
bits per word를 8로 설정: 약 0.143초 (~800kb/s)
bits per word를 32로 설정: 약 0.096초 (~1,200kb/s)
하드커널에서 재공하는 커널은 bits per word를 64로 사용가능한것으로 보이지만 현재 사용하는 커널은 Vanilla Kernel이고 bits per word를 64로 설정하지 못하므로 나중에 기회되면 확인필요 (소스코드, 포럼 글) - 라즈베리파이 3B+ 기준, 약 115kb 동일 데이터 전송에 걸리는 시간
bits per word를 8로 설정: 약 0.045초 (~2,555kb/s)
16, 32 둘 다 설정이 불가능하여 확인불가 (이미 압도적으로 빠르다) - 결과적으로 240×240 해상도의 SPI 인터페이스 LCD를 연결할경우 라즈베리파이는 34~35프레임으로 부드러워 보이지만 오드로이드는 9~10프레임으로 부드러운 애니메이션 표현이 불가능
- Vanilla Kernel 기준, 약 115kb 전송에 걸리는 시간
기타
- sdcard로 이미지 쓰기 시 progress 정상표시 (olfsg=dsync)
dd if=sdcard.img of=/dev/sdX bs=1M oflag=dsync status=progress - 5.11.22버전 부터는 End-of-Life로 분류되어 5.10버전과 5.12버전 기준으로 내용 변경
- EGL_PLATFORM_GBM_KHR으로 생성한 EGL 인터페이스로 off screen 렌더링을 수행 시 프래임마다 glFlush()를 호출하지않으면 메모리 사용량이 계속 늘어남(GL 인터페이스 규격 사항 때문으로 보임)
사용중인 환경
- 리눅스 배포본: 젠투리눅스
- 파일시스템: zfs
- Kernel Config: (아래 첨부)
2021-10-23 현재 커널버전 5.14.13까지 vanilla 커널을 사용을 끝으로 커널 패닉을 감당하기 힘들어 하드커널에서 배포하는 커널로 복귀. 2021버전으로 빌드하여 사용한 u-boot의 차이인지 어디에서 문제인지 확인이 불가능.
기왕 최신 커널을 포기한거 그냥 ASUS의 Tinker Board 2나 Tinker Board 2S로 눈 돌릴까 생각이 든다. 애초 SPI 드라이버가 DMA 방식을 사용하지 않아서 그런지 GPIO에 간섭받는 문제있고 CPU의 처리 속도차이는 어느정도인지 몰라도 3D 가속 능력은 그리 중요하지 않아서 N2의 GPU가 더 최신 아키텍처이지만 별 의미가 없어보인다. (USB-C 모니터를 쓸 수 있는건 덤) 프로그래밍을 끝낸 지금은 SPI 성능이 훨씬 좋은 라즈베리파이로 옮겨서 사용중이지만 나중에 다시 SPI 인터페이스로 프로그래밍을 하게되면 Tinker Board 구입을 다시 생각 해 봐야겠다.
2024-07-24 오랜만에 구동 중 PWM 쿨러의 동작 온도를 내리기 위해 dts 파일을 확인한 내용 추가. 아래는 odroid n2+에서 주로 사용하는 dts 파일들
/usr/src/linux/arch/arm64/boot/dts/amlogic/mesong12b.dtsi
/usr/src/linux/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dtsi
/usr/src/linux/arch/arm64/boot/dts/amlogic/meson64_odroidn2_plus.dts
위 파일 중 mesong12b.dtsi 파일을 열면 pswitch_on으로 정의 된 항목이 있으며 temperature 값을 65000에서 45000으로 변경 후 저장하여 커널 소스에서 make dtbs를 실행, /usr/src/linux/arch/arm64/boot/dts/amlogic/meson64_odroidn2_plus.dtb 파일을 부트 파티션 내 meson64_odroidn2_plus.dtb파일을 덮어씌우면 45도에서도 PWM 팬이 동작한다. overlay로 변경하는 방법은 추후 시간되면 확인.