RK3568设备西瓜皮v3适配immortalwrt

 

适配设备信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# NL68K 西瓜皮V3购买链接:https://item.taobao.com/item.htm?id=711773675433
# MINIPCIE转5G模块转接板:https://item.taobao.com/item.htm?id=694045271626

# 西瓜皮v3硬件配置,包括核心板V3一片,西瓜皮V3底板一片
CPU:瑞芯微 RK3568 四核64位Cortex-A55 Mail-G52 RK817-5
ROM:闪迪 SanDisk SDINBDA4-32G 32GB eMMC
RAM:长鑫 CXMT CXDB5CCBM-MK-A 4GB LPDDR4X

2个 RTL8211F 自带千兆网口
2个 MINIPCIE 接口,带5V电源PA供电专用,可插PCIE的WIFI网卡
1个 M.2 B Key接口,支持RM500Q同尺寸的 5G 模块(52×30×2.3mm)
1个 M.2 E Key接口,支持MT7922同尺寸的WiFi网卡(22x30x2.3mm)
1个 USBA3 OTG接口 1个 HDMI2.0输出接口 1个 TF卡槽 1个 SIM卡槽
1个 DC 5521规格的电源插头,可使用5V-18V 1-3A
1个 FPC接口的 SPI/I2C 显示屏接口,CNC外壳上带的SPI屏幕驱动IC为GC9307
1个 可自动根据CPU温度调节风扇转速的5V风扇接口 XH1.25 4pin PWM调速
3个 LED指示灯 3个按钮:| ⊙ 刷机键 | ↺ 重启键 | ○ 恢复键 |

获取官方源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 下载源码(--single-branch 仅下载单个分支/标签、--depth=1 只下载最新的一次提交、-b 指定分支/标签)
git clone --depth=1 -b v24.10.1 https://github.com/immortalwrt/immortalwrt
cd immortalwrt/
git pull
./scripts/feeds update -a
./scripts/feeds install -a

make menuconfig # 进入固件配置界面增减改查
make download V=s -j$(nproc) # 请尽量用梯子下载所需源码
make V=s -j$(nproc) # 若编译出错请用单线程调错

# 常用网卡驱动所需驱动包,MT7921有3种版本,E是PCIE,S是SDIO,U是USB,没别的区分。RTL8852也有多种版本
MT7915/MT7916 kmod-mt7915e kmod-mt7915-firmware kmod-mt7916-firmware
MT7921/MT7922/MT7925E kmod-mt7921[e/s/u] kmod-mt7921-firmware kmod-mt7922-firmware kmod-mt7925e kmod-mt7925-firmware
AX500-DBS/NFA765 kmod-ath11k kmod-ath11k-pci ath11k-firmware-qca6390 ath11k-firmware-wcn6855
AX200/AX210/BE200 kmod-iwlwifi iwlwifi-firmware-ax200 iwlwifi-firmware-ax210 iwlwifi-firmware-be200
RTL8852[A/B/C]E/RTL8922AE kmod-rtw89-8852[a/b/c]e rtl8852[a/b/c]e-firmware kmod-rtw89-8922ae rtl8922ae-firmware

# 蓝牙固件
MT7921/MT7922 mt7921bt-firmware mt7922bt-firmware

开始适配设备

  1. target/linux/rockchip/image/armv8.mk 文件最后添加如下内容,使其出现在 make menuconfig 里面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# target/linux/rockchip/image/armv8.mk

define Device/nlnet_xgp
DEVICE_VENDOR := NLnet
DEVICE_MODEL := XiGuaPi
SOC := rk3568
DEVICE_DTS := rockchip/rk3568-xgp-v3
UBOOT_DEVICE_NAME := xgp-rk3568
BOOT_FLOW := pine64-img
DEVICE_PACKAGES := wpad-openssl kmod-mt7916-firmware kmod-r8169 \
usbutils pciutils luci luci-ssl-openssl luci-proto-ncm luci-proto-mbim
endef
TARGET_DEVICES += nlnet_xgp

  1. 添加适配设备名到指定文件使其可初始化网络和优化网络设备性能,记得不要包含 + 号哦
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
# 将如下带 + 的行添加到:target/linux/rockchip/armv8/base-files/etc/board.d/02_network

rockchip_setup_interfaces()
{
local board="$1"

case "$board" in
+ nlnet,xgp|\
armsom,sige7|\
......
rockchip_setup_macs()
{
local board="$1"
local lan_mac=""
local wan_mac=""
local label_mac=""

case "$board" in
+ nlnet,xgp|\
armsom,sige3|\

---------------------------------------------------------------------------------------------------
# 将如下带 + 的行添加到:target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity

case "$(board_name)" in
+ nlnet,xgp|\
armsom,sige3|\

  1. 在内核源码中为需要适配的设备添加设备树
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 获取适配设备的DTS并将其放到指定位置,在immortalwrt构建时该文件会复制到内核源码中
cd target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/
wget https://github.com/6ang996/lede/raw/rk356x-xgp_support/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nlnet-xgz68.dtsi
wget https://github.com/6ang996/lede/raw/rk356x-xgp_support/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xgp-v3.dts
wget https://github.com/6ang996/lede/raw/rk356x-xgp_support/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xgp.dts

# 有了DTS还需要在Makefile中添加,在如下补丁中添加如下带 + 的行,建议直接用它替换补丁中已存在的行,让构建immortalwrt时应用补丁到内核源码中
---------- target/linux/rockchip/patches-6.6/900-arm64-boot-add-dts-files.patch ----------
diff -Nur a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -114,3 +114,4 @@
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-xgp-v3.dtb

  1. U-Boot中添加本适配的设备
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
31
# 首先在 package/boot/uboot-rockchip/Makefile 中添加本适配设备

define U-Boot/xgp-rk3568
$(U-Boot/rk3568/Default)
NAME:=XGP Board
BUILD_DEVICES:= \
nlnet_xgp
endef

UBOOT_TARGETS := \
xgp-rk3568 \
......

# 我这里使用官方支持的相近配置的设备 Armsom-Sige3 的配置及别人适配好的设备树,也可全部用 Armsom-Sige3 的设备树及配置文件
cd package/boot/uboot-rockchip/src/arch/arm/dts/
wget https://github.com/x-shark/immortalwrt/raw/master/package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp.dts
wget https://github.com/x-shark/immortalwrt/raw/master/package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp-u-boot.dtsi
# 这个文件 rk3568-xgp-u-boot.dtsi 不存在或内容不对虽然编译时不会报错,但会因U-Boot损坏而无法启动

# 使用U-Boot中已适配好的设备 Armsom-Sige3 的配置文件,也可直接用 Armsom-Sige3 的设备树,该配置中指定了使用的设备树文件
cd package/boot/uboot-rockchip/src/configs && cp sige3-rk3568_defconfig xgp-rk3568_defconfig

# 将上面拷贝的 Armsom-Sige3 配置文件中的设备树修改为要适配设备的:package/boot/uboot-rockchip/src/configs/xgp-rk3568_defconfig
# CONFIG_DEFAULT_DEVICE_TREE="rk3568-armsom-sige3" 替换为 CONFIG_DEFAULT_DEVICE_TREE="rk3568-xgp"
# CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-armsom-sige3.dtb" 替换为 CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-xgp-v3.dtb"
# 拷贝的 Armsom-Sige3 配置文件不修改也能直接用,但因用的是Sige3的设备树,在U-Boot中会显示为:Model: ArmSoM Sige3 不影响正常启动

# 在 package/boot/uboot-rockchip/Makefile 中已指定了配置文件名为:[xgp-rk3568]_defconfig
# 在 xgp-rk3568_defconfig 中 CONFIG_DEFAULT_DEVICE_TREE 已指定了使用的DTS为:[rk3568-xgp].dts
# 在 xgp-rk3568_defconfig 中 CONFIG_DEFAULT_FDT_FILE 指定了在U-Boot中默认加载的设备树文件,Armbian中有用,而OpenWrt中用不上

驱动 SPI屏幕

  1. 自带的SPI屏幕驱动器为GC9307,而它几乎与ST7789V相同,所以这里拿ST7789V模块改下来用

  2. 首先在 immortalwrt/package/kernel/linux/modules/video.mk 中添加如下内容使能在菜单中选择ST7789V内核模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 在 menuconfig 中的位置 > Kernel modules > Video Support > <*> kmod-fb-tft-st7789v

define KernelPackage/fb-tft-st7789v
SUBMENU:=$(VIDEO_MENU)
TITLE:=FB driver for the ST7789V LCD Controller
DEPENDS:=+kmod-fb-tft
KCONFIG:=CONFIG_FB_TFT_ST7789V
FILES:=$(LINUX_DIR)/drivers/staging/fbtft/fb_st7789v.ko
AUTOLOAD:=$(call AutoLoad,09,fb_st7789v)
endef

define KernelPackage/fb-tft-st7789v/description
FB driver for the ST7789V LCD Controller
endef

$(eval $(call KernelPackage,fb-tft-st7789v))

  1. 再将如下内容的补丁放到 immortalwrt/target/linux/rockchip/patches-6.6/999-Add-GC9307.patch 中使内核能驱动这款屏幕
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -28,7 +28,7 @@
"D0 05 0A 09 08 05 2E 44 45 0F 17 16 2B 33\n" \
"D0 05 0A 09 08 05 2E 43 45 0F 16 16 2B 33"

-#define HSD20_IPS 1
+#define HSD20_IPS 0

/**
* enum st7789v_command - ST7789V display controller commands
@@ -289,7 +289,7 @@
default:
return -EINVAL;
}
- write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
+ write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0x38);
return 0;
}


  1. 修改 immortalwrt/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-xgp*.dts 设备树中的spi3节点为如下内容
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
......
&spi3 {
pinctrl-names = "default";
pinctrl-0 = <&spi3m1_cs0 &spi3_sck &spi3_mosi>;
status = "okay";
display@0 {
pinctrl-names = "default";
pinctrl-0 = <&spi3_display_dc_pin &display_reset_pin>;
compatible = "sitronix,st7789v";
reg = <0>;
rotate = <270>;
dc-gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;
backlight = <&backlight>;
buswidth = <8>;
debug = <0x0>;
mirror-y;
status = "okay";
};
};
......
&pinctrl {
spi3 {
spi3_sck: spi3_sck {
rockchip,pins = <4 RK_PC2 2 &pcfg_pull_none>;
};
spi3_mosi: spi3_mosi {
rockchip,pins = <4 RK_PC3 2 &pcfg_pull_none>;
};
};

display {
spi3_display_dc_pin: spi3_display_dc_pin {
rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
display_reset_pin: display_reset_pin {
rockchip,pins = <4 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};

backlight {
backlight_led_pin: backlight-led-pin {
rockchip,pins = <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
......

  1. 内核显示输出及简单的显示测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@ImmortalWrt:~# dmesg | grep fb
[ 9.233927] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[ 9.251168] fb_st7789v: module is from the staging directory, the quality is unknown, you have been warned.
[ 9.252287] SPI driver fb_st7789v has no spi_device_id for sitronix,st7789v
[ 9.253148] fb_st7789v spi3.0: fbtft_property_value: buswidth = 8
[ 9.253693] fb_st7789v spi3.0: fbtft_property_value: backlight = 157
[ 9.254256] fb_st7789v spi3.0: fbtft_property_value: debug = 0
[ 9.254772] fb_st7789v spi3.0: fbtft_property_value: rotate = 270
[ 9.530937] graphics fb0: fb_st7789v frame buffer, 320x240, 150 KiB video memory, 4 KiB buffer memory, fps=20, spi3.0 at 50 MHz
root@ImmortalWrt:~#

cat /dev/urandom > /dev/fb0 # 显示花屏
cat /dev/zero > /dev/fb0 # 清空屏幕,也就是黑屏

其他优化项目

  1. 添加QModem移动模组管理程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 添加该项目源码后更新并安装,然后就可以在后面的 menuconfig 中选择构建使用了
echo 'src-git qmodem https://github.com/FUjr/QModem.git;main' >> feeds.conf.default
./scripts/feeds update qmodem
./scripts/feeds install -a -p qmodem

# > LuCI > 3. Applications > <*> luci-app-qmodem
│ │ -*- luci-app-qmodem.............................. LuCI support for QWRT Modem │ │
│ │ Qualcomm QMI WWAN Driver Selection (Vendor QMI driver) ---> │ │
│ │ Quectel Connect Manager Selection (Tom customized Quectel CM) ---> │ │
│ │ [*] Add PCIe Modem SUPPORT │ │
│ │ [*] Add MTK-T7XX Modem PCI SUPPORT │ │
│ │ [*] Add Qfirehose SUPPORT │ │
│ │ < > luci-app-qmodem-hc............................ Luci qwrt modem sim switch │ │
│ │ < > luci-app-qmodem-mwan........................ Luci qwrt modem mwan support │ │
│ │ <*> luci-app-qmodem-sms.......................... Luci qwrt modem sms support │ │
│ │ < > luci-app-qmodem-ttl.......................... Luci qwrt modem ttl support │ │

# 注意:luci-app-qmodem 与 luci-proto-quectel 中的 quectel-cm 中的如下两个依赖包冲突。在 immortalwrt/feeds/packages/net/quectel-cm/Makefile 中有记载
+kmod-usb-net-qmi-wwan-fibocom \
+kmod-usb-net-qmi-wwan-quectel \

  1. 修改U-Boot启动顺序默认从SD卡启动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# RK3568默认u-boot的SPL有个启动次序,比如 MMC2 -> MMC1,那么该如何修改这个顺序呢?

# RK35XX的MMC大致分为3种设备:
SDMMC sdmmc用于SD卡通信
SDHCI sdhci用于EMMC通信
SDIO sdio用于wifi等外设通信

# 在源码 u-boot-2024.10/include/configs/rockchip-common.h 中已经定义了默认的启动顺序如下:
#define BOOT_TARGETS "mmc1 mmc0 nvme scsi usb pxe dhcp spi"

# 所以要把sdhci即EMMC设为0,sdmmc即SD卡设为1。这样当有mmc1即SD卡存在时,便会从其启动。SD卡不存在时,则从mmc0启动
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc0;
};

# 可能涉及到如下文件的修改
package/boot/uboot-rockchip/src/arch/arm/dts/rk3568-xgp.dts
target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nlnet-xgz68.dtsi

  1. 修改构建后系统默认使用的软件源
1
2
3
4
5
# 以将源地址 https://downloads.immortalwrt.org 或 https://mirrors.vsean.net/openwrt 更改为 https://mirrors.cernet.edu.cn/immortalwrt 为例
# 将该文件中 opkg_mirror 值修改为如下即可:immortalwrt/package/emortal/default-settings/files/99-default-settings-chinese
opkg_mirror="https://mirrors.vsean.net/openwrt" 修改为 opkg_mirror="https://mirrors.cernet.edu.cn/immortalwrt"

# 而默认的自定义源存储在:immortalwrt/package/system/opkg/files/customfeeds.conf
  1. 调整内核后缀与immortalwrt官方源中版本一致来使用官方源中的内核模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 首先查看要用的immortalwrt源中内核的版本信息
leux@Debian:~$ curl -s https://downloads.immortalwrt.org/releases/24.10.1/targets/rockchip/armv8/immortalwrt-24.10.1-rockchip-armv8.manifest | grep kernel
kernel - 6.6.86~422144fea623288f7402e1a9a15724c8-r1

# 将 immortalwrt/include/kernel-defaults.mk 中第 130 行如下内容注释并在其后添加另一行
......
# grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | $(MKHASH) md5 > $(LINUX_DIR)/.vermagic
cp $(TOPDIR)/.vermagic $(LINUX_DIR)/.vermagic
......

# 将源中内核的后缀添加到immortalwrt源码根目录,后续内核编译时会将其拷贝到内核源码根目录并将其内容作为内核后缀
leux@Debian:~/immortalwrt$ echo "422144fea623288f7402e1a9a15724c8" > ~/immortalwrt/.vermagic

# 最后生成的内核包在:~/immortalwrt/bin/targets/rockchip/armv8/packages/kernel_6.6.86~422144fea623288f7402e1a9a15724c8-r1_aarch64_generic.ipk

# 刷入该系统后可更换默认软件源为国内源,如下首行KMOD源即是上面后缀一致可用的官方内核模块源
src/gz immortalwrt_kmod https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/targets/rockchip/armv8/kmods/6.6.86-1-422144fea623288f7402e1a9a15724c8
src/gz immortalwrt_core https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/targets/rockchip/armv8/packages
src/gz immortalwrt_base https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/packages/aarch64_generic/base
src/gz immortalwrt_luci https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/packages/aarch64_generic/luci
src/gz immortalwrt_packages https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/packages/aarch64_generic/packages
src/gz immortalwrt_routing https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/packages/aarch64_generic/routing
src/gz immortalwrt_telephony https://mirrors.ustc.edu.cn/immortalwrt/releases/24.10.1/packages/aarch64_generic/telephony

  1. 将 RM500Q 从 USB 切换到 PCIE,需要用到开头配套的 miniPCIE转5G转接板,先在USB模式下通过AT命令切换成PCIE模式,然后再插到转接板上就行了
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
31
32
33
34
35
36
37
38
# 注意:一旦切换为PCIE模式并重启后,/dev/ttyUSB* 之类的AT端口将消失,若你没有让模块支持PCIE模式的接口或转接板,还在USB接口下模块将因失去联系而无法调回

# 这几个指令是模块重启才生效的
AT+QCFG="USBNET",0
AT+QCFG="pcie/mode",0 # 默认为 0: EP mode. 1: RC mode. (PCIe运行模式:EP模式:外接设备,用电脑CPU。RC模式:主机模式,用模块的CPU)
AT+QCFG="data_interface",1,0 # 切换为PCIE通信端口,只能是 1,0
AT+QCFG="data_interface",0,0 # 切换为 USB通信端口,只能是 0,0

# 用QModem程序从终端切换为USB和PCIE的命令。若PCIE加载不上,可在计划项里添加:echo 1 > /sys/bus/pci/rescan
tom_modem -d /dev/ttyUSB2 -c 'AT+QCFG="data_interface",0,0'
tom_modem -d /dev/ttyUSB2 -c 'AT+QCFG="data_interface",1,0'

# 出厂默认的为 USB 模式显示如下:
AT+QCFG="pcie/mode" >> /dev/ttyUSB3
AT+QCFG="pcie/mode"

+QCFG: "pcie/mode",0

OK
<<EOF
AT+QCFG="data_interface" >> /dev/ttyUSB3
AT+QCFG="data_interface"

+QCFG: "data_interface",0,0

OK
<<EOF

———————————————————————————————————————————————————————————————————————————————————
接口路径 | 主要功能 | 应用场景 |
———————————————————————————————————————————————————————————————————————————————————
/dev/mhi_BHI | Modem启动和寄存器访问 | 固件加载、硬件调试 |
/dev/mhi_DIAG | 诊断日志传输 | 信号分析、故障排查 |
/dev/mhi_DUN | AT命令交互 | 拨号上网、设接入点 |
/dev/mhi_LOOPBACK | 数据环回测试 | 驱动验证、链路自检 |
/dev/mhi_QMI0 | QMI协议通信 控制 数据 | 模块管理及数据传输 |
———————————————————————————————————————————————————————————————————————————————————

  1. 其他零碎的小知识
1
2
3
4
5
6
7
8
9
# 一个可查询软件包相关信息的网站:https://openwrt.pkgs.org/

# 在 /usr/lib/opkg/status 和 /usr/lib/opkg/info/ 中存储着opkg已安装的软件包相关信息

# 内核中查看温度
cpu_thermal cat /sys/class/hwmon/hwmon0/temp1_input
gpu_thermal cat /sys/class/hwmon/hwmon1/temp1_input
ath11k_hwmon cat /sys/class/hwmon/hwmon2/temp1_input