1. 拿到RK3568这块板子之后,先想清楚点屏这件事到底难在哪
很多人第一次在OpenHarmony上折腾RK3568点屏,心态都是这样的:源码拉下来,编译一把过,烧进去,屏幕就该亮了。结果往往是——串口有打印,HDMI没信号,MIPI屏背光都不亮,或者亮了但花屏、偏移、颜色不对。然后就开始漫无目的地搜"rk3568 点屏",翻到一堆碎片化的帖子,改一个参数编译半小时,烧录五分钟,看结果三秒钟,一天下来屏幕还是黑的。
我前后在RK3568上点过MIPI DSI屏、RGB屏、LVDS转接屏,也踩过触摸方向不对、背光时序不匹配、设备树节点被覆盖这些坑。这篇文章不讲空泛的概念,就按我实际操作的顺序,把从源码编译到内核配置调优这条链路完整走一遍。适合已经拿到RK3568开发板、准备在OpenHarmony 5.1.0上点亮一块屏的开发者,也适合之前点过Android或纯Linux、但第一次接触OpenHarmony显示子系统的朋友。
先说清楚一个认知:点屏从来不是"改一个参数"的事,它是"编译系统 + 内核配置 + 设备树 + 显示驱动 + 背光 + 触摸"这一整条链路的协同结果。任何一环不对,屏幕都不会给你好脸色。所以下面我会按这条链路的顺序展开,每一环都告诉你为什么这么做、怎么验证、错了会怎样。
2. OpenHarmony 5.1.0 源码编译:别急着make,先把环境对齐
2.1 编译环境的选择与依赖安装
OpenHarmony 5.1.0的编译对Ubuntu版本有要求,我实测下来Ubuntu 20.04和22.04都能跑通,但22.04上某些Python依赖需要额外处理。建议直接用20.04,省心。内存至少16GB,低于这个数编译到图形子系统那一步大概率OOM,我见过8GB机器编译到一半被kill的,报错信息还特别隐晦,让人以为是代码问题。
依赖安装这一步,官方文档给的包列表是基础,但实际编译RK3568的图形栈时还会缺一些。我习惯一次性把下面这些装齐:
sudo apt-get update sudo apt-get install -y git-lfs build-essential gcc g++ make sudo apt-get install -y libssl-dev libncurses5-dev libncursesw5-dev sudo apt-get install -y python3 python3-pip python3-venv sudo apt-get install -y genext2fs mtools dosfstools sudo apt-get install -y device-tree-compiler sudo apt-get install -y liblz4-tool其中device-tree-compiler(也就是dtc)特别关键,后面设备树的编译和反编译全靠它。很多人编译报错"dtc not found",就是漏了这个。
Python环境我强烈建议用虚拟环境隔离,不要污染系统Python。OpenHarmony的编译脚本对Python版本敏感,系统里如果混了多个版本,会出现"明明装了模块却import失败"的诡异现象。
python3 -m venv ~/ohos-env source ~/ohos-env/bin/activate pip3 install --upgrade pip pip3 install pycryptodome提示:每次开新终端编译前,记得先
source ~/ohos-env/bin/activate,否则编译脚本会去找系统Python,报错信息往往指向一个和Python毫无关系的模块,排查起来很浪费时间。
2.2 拉取源码与RK3568产品配置
源码用repo工具管理,先装repo,再初始化。这里有个细节:OpenHarmony 5.1.0的分支名要选对,用错分支会导致RK3568的板级配置目录根本不存在。
mkdir ~/ohos && cd ~/ohos repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony-5.1.0-Release --no-repo-verify repo sync -c repo forall -c 'git lfs pull'repo sync这一步耗时很长,网络不稳的话建议加-j4控制并发,别贪多。同步完之后,进入device/board/目录看看有没有rk3568相关的板级目录,这是判断源码是否完整的第一道关卡。
编译命令针对RK3568通常是这样:
./build.sh --product-name rk3568 --ccache--ccache强烈建议加上,第一次编译可能40分钟到1小时,之后增量编译能压到几分钟。没有ccache的话,你每改一次设备树都要等一次完整编译,心态会崩。
2.3 编译产物里到底哪个文件才是你要烧的
编译完成后,产物在out/rk3568/packages/phone/images/目录下。这里要认清几个关键镜像:
| 镜像文件 | 作用 | 点屏相关度 |
|---|---|---|
| boot.img | 内核+设备树 | 极高,设备树改动主要在这里 |
| system.img | 系统分区 | 中,显示框架配置可能涉及 |
| vendor.img | 厂商分区 | 中,HDF显示驱动配置 |
| userdata.img | 用户数据 | 低 |
| uboot.img | 引导程序 | 中,开机logo和显示初始化 |
点屏调试阶段,改得最多的就是boot.img,因为设备树(dtb)被打包在里面。每次改完设备树,重新编译后只需要烧boot.img就能验证,不用全量烧录,这个技巧能帮你省下大量时间。
3. 内核配置:显示相关的开关一个都不能少
3.1 为什么默认配置点不亮屏
OpenHarmony给RK3568的默认内核配置(defconfig)是一个"能跑起来"的最小集合,它保证了系统启动,但显示相关的驱动模块很多是没开的。这就解释了为什么很多人烧完默认镜像,串口一切正常,屏幕却毫无反应——内核里压根没加载对应的显示驱动。
RK3568的显示子系统涉及几个关键部分:VOP(Video Output Processor,视频输出处理器)、MIPI DSI控制器、背光PWM控制器、以及具体的屏panel驱动。这些在menuconfig里分散在不同菜单下,需要逐个确认。
进入内核配置:
cd kernel/linux/linux-5.10 make ARCH=arm64 rockchip_defconfig make ARCH=arm64 menuconfig3.2 必须确认打开的关键配置项
下面这些配置项是我点屏时逐个核对过的,缺一个都可能导致屏幕不亮或者亮得不正常:
CONFIG_DRM=y CONFIG_DRM_ROCKCHIP=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_DRM_PANEL=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_PWM=y CONFIG_PWM_ROCKCHIP=y CONFIG_DRM_PANEL_SIMPLE=y CONFIG_PHY_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y其中CONFIG_DRM_PANEL_SIMPLE是通用panel驱动,如果你用的屏没有专门的驱动,靠它配合设备树里的panel描述就能点亮。CONFIG_PHY_ROCKCHIP_INNO_VIDEO_COMBO_PHY是MIPI DPHY的驱动,MIPI屏没它直接黑屏。
注意:改完menuconfig后,不要直接
make savedefconfig覆盖原defconfig,除非你确定要永久修改。调试阶段建议保留.config,验证通过后再决定是否固化到defconfig。
3.3 内核配置的验证方法
配置改完编译出boot.img后,怎么确认驱动真的加载了?最直接的办法是看启动日志:
dmesg | grep -i -E "drm|vop|dsi|panel|backlight"如果看到类似rockchip-drm display-subsystem: bound、panel-simple相关的probe成功信息,说明驱动加载正常。如果只有VOP绑定成功但没有panel,那问题就在设备树里panel节点没配对。
我遇到过一次,dmesg里显示failed to find panel,查了半天发现是设备树里panel节点的compatible字符串和驱动里注册的不一致。这种问题日志里其实写得很清楚,关键是要养成看dmesg的习惯,而不是盯着黑屏瞎猜。
4. 设备树配置:点屏的核心战场
4.1 设备树在RK3568显示链路里的角色
设备树(Device Tree)本质上是把"硬件长什么样"这件事从内核代码里剥离出来,用一份描述文件告诉内核:这块板子上接了哪个屏、用哪路MIPI、背光接在哪个PWM、复位脚是哪个GPIO。内核启动时解析这份描述,去匹配对应的驱动。
RK3568的设备树文件在kernel/linux/linux-5.10/arch/arm64/boot/dts/rockchip/目录下,和RK3568相关的主要是rk3568.dtsi(SoC级公共描述)和具体的板级dts文件(比如rk3568-evb1-ddr4-v10.dts之类)。改的时候要改板级dts,不要动dtsi,dtsi是所有RK3568板子共用的,改了会影响其他配置。
4.2 MIPI DSI屏的设备树节点怎么写
一块MIPI屏要工作,设备树里至少要描述清楚四件事:DSI控制器、panel本身、背光、供电和复位。下面是一个我实际用过的结构,以一块常见的MIPI屏为例:
&dsi0 { status = "okay"; rockchip,lane-rate = <1000>; panel: panel@0 { compatible = "simple-panel-dsi"; reg = <0>; backlight = <&backlight>; reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; enable-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST)>; dsi,format = <MIPI_DSI_FMT_RGB888>; dsi,lanes = <4>; display-timings { native-mode = <&timing0>; timing0: timing0 { clock-frequency = <68000000>; hactive = <800>; vactive = <1280>; hback-porch = <40>; hfront-porch = <40>; hsync-len = <10>; vback-porch = <20>; vfront-porch = <20>; vsync-len = <4>; }; }; }; };这里每一个参数都不是随便填的。clock-frequency是像素时钟,由分辨率、刷新率和消隐区共同决定,填错了要么花屏要么刷新率不对。dsi,lanes要和屏的物理排线一致,4 lane的屏写成2 lane,直接黑屏。dsi,format要和屏的接口定义匹配,RGB888和RGB565搞混,颜色会明显失真。
4.3 背光节点:屏幕亮了但很暗,八成是这里
背光是最容易被忽略的一环。屏幕能显示内容但亮度极低,或者完全不亮,问题往往出在背光节点。RK3568的背光通常走PWM:
backlight: backlight { compatible = "pwm-backlight"; pwms = <&pwm4 0 25000 0>; brightness-levels = < 0 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 /* 中间省略,实际要写满256级 */ 255 >; default-brightness-level = <200>; enable-gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>; };pwms里的25000是PWM周期,单位纳秒,对应40kHz,这是大多数背光IC能接受的频率。频率太低会有可听噪声,太高有些背光IC响应不过来。brightness-levels是一张亮度映射表,OpenHarmony的背光框架会按这个表来调光,如果表里全是0,那屏幕就是黑的。
我踩过一个坑:enable-gpios的极性写反了,结果背光一直是关的,但dmesg里没有任何报错,因为从内核角度看PWM输出是正常的,只是使能脚电平不对。这种问题只能靠万用表量电压或者示波器看波形来定位。
4.4 触摸屏方向不对怎么改
触摸方向不对是RK3568点屏的高频问题,尤其是竖屏改横屏的场景。触摸芯片(比如GT9xx、FT5x06)通过I2C接入,方向由设备树里的touchscreen-inverted-x、touchscreen-inverted-y、touchscreen-swapped-x-y这几个属性控制:
&i2c3 { status = "okay"; gt9xx: gt9xx@5d { compatible = "goodix,gt9xx"; reg = <0x5d>; touch-gpio = <&gpio0 RK_PB5 IRQ_TYPE_LEVEL_LOW>; reset-gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>; touchscreen-inverted-x; touchscreen-swapped-x-y; }; };竖屏改横屏,通常需要同时调整swapped-x-y和其中一个inverted。具体怎么组合,取决于屏的物理安装方向,没有万能公式,得试。我的经验是:先只加swapped-x-y看效果,如果方向对了但上下反了,再加inverted-y;如果左右反了,加inverted-x。每次只改一个属性,改完单独编译boot.img验证,这样能快速定位到正确的组合。
5. 从编译到烧录再到验证的完整闭环
5.1 单独编译设备树和内核的高效方法
全量编译一次要几十分钟,但调试设备树时完全没必要全量编。改完dts后,可以只编内核:
./build.sh --product-name rk3568 --build-target kernel --ccache这样只重新编译内核和设备树,几分钟就能出新的boot.img。更进一步,如果只是想验证设备树语法,可以单独用dtc编译:
dtc -I dts -O dtb -o test.dtb rk3568-your-board.dts这一步能快速发现语法错误,比如括号不匹配、属性名拼错,不用等整个内核编译完才报错。
5.2 烧录工具与分区选择
RK3568烧录一般用瑞芯微的烧录工具,进入loader模式后连接。调试阶段我建议只烧boot.img,因为设备树和内核都在里面。烧录前确认板子确实进了loader模式,否则工具会提示找不到设备。
烧录完成后,串口工具(波特率1500000,这是RK3568的默认调试串口波特率,不是常见的115200,很多人卡在这里以为串口坏了)看启动日志。重点看几个时间点:uboot阶段有没有识别到显示设备、内核阶段drm和panel有没有probe成功、系统起来后显示服务有没有正常启动。
5.3 分层排查:屏幕不亮时按这个顺序查
屏幕不亮的原因可能分布在链路的任何一层,盲目乱改效率极低。我总结的排查顺序是这样的:
| 排查层级 | 检查内容 | 判断依据 |
|---|---|---|
| 硬件层 | 排线、供电、背光电压 | 万用表量电压,示波器看信号 |
| uboot层 | 开机logo是否显示 | 有logo说明基础显示通路OK |
| 内核层 | dmesg里drm/panel/vop日志 | probe成功与否 |
| 设备树层 | 节点status、compatible、时序参数 | 与屏规格书逐项核对 |
| 框架层 | OpenHarmony显示服务日志 | 系统起来后屏幕有无内容 |
按这个顺序从下往上查,能快速缩小范围。比如uboot阶段就有logo,说明VOP和基本的显示通路没问题,问题大概率在panel驱动或设备树时序上;如果uboot阶段就没logo,那要往更底层查,可能是uboot的显示配置或者硬件本身的问题。
6. 几个让我印象深刻的坑和对应的解法
6.1 设备树节点被覆盖导致配置不生效
有一次我明明在板级dts里把panel节点配好了,编译烧录后却完全没效果。查了很久才发现,板级dts里include了一个公共的dtsi,那个dtsi里也定义了同名节点,而且顺序在后,把我的配置覆盖了。设备树的节点合并规则是:后出现的属性覆盖先出现的,同名节点会合并而不是替换。
解法是确认include顺序,或者用/delete-node/先删掉再重新定义。这个坑的隐蔽性在于编译不报错,日志也不报错,就是配置不生效,非常折磨人。
6.2 时序参数差一点就花屏
MIPI屏的时序参数(前后消隐、同步宽度)必须严格按屏规格书来。我有一次把hback-porch少写了一个0,屏幕能亮但右侧有一条竖条纹,看起来像是屏坏了。实际上就是消隐区不够,数据没对齐。这种问题改回正确参数立刻就好,但如果不熟悉时序原理,很容易误判成硬件故障。
6.3 背光PWM频率引起的闪烁
背光用低频PWM驱动时,肉眼可能看不出闪烁,但拍照或者录像时会出现明显的横纹。我遇到过PWM频率设成1kHz的情况,屏幕看着正常,但用手机拍就有条纹。把频率提到20kHz以上就消失了。所以背光PWM频率建议不低于20kHz,既避开可听噪声,也避开可见闪烁。
6.4 触摸和显示不同步
偶尔会遇到显示正常但触摸坐标完全错乱的情况,尤其是换了屏但没同步更新触摸配置的时候。触摸的坐标系是独立的,显示旋转了不代表触摸也跟着转。解决办法就是在触摸节点里正确配置swapped-x-y和inverted属性,让触摸坐标系和显示坐标系对齐。这个必须实测,没有捷径。
7. 调优阶段值得花时间做的几件事
屏幕点亮只是第一步,点亮之后还有调优空间。第一件事是确认刷新率是否达标,用modetest或者系统自带的显示信息接口看实际刷新率,如果和屏规格书差太多,回头检查clock-frequency和消隐参数。第二件事是背光曲线,默认的线性映射在低亮度区往往偏亮,可以自定义brightness-levels做成非线性曲线,低亮度更细腻。第三件事是开机logo到系统界面的过渡,如果uboot显示了logo但系统起来后黑一下再亮,说明显示通路上有重新初始化的动作,可以通过调整uboot和内核的显示配置减少这段黑屏时间。
RK3568这块芯片的显示能力其实挺强,多路VOP、MIPI、LVDS、RGB都支持,点屏过程中积累的设备树配置经验,换一块屏或者换一个分辨率,大部分是可以复用的。真正需要重新调的,往往就是panel节点里的时序参数和触摸方向这几项。把这条链路走通一次之后,后面再点新屏,速度会快很多。
最后分享一个我自己的习惯:每点通一块屏,就把对应的设备树片段、内核配置差异、以及踩过的坑记成一个独立的patch文件存起来。下次遇到类似型号的屏,直接参考patch改,比翻聊天记录和搜索历史靠谱得多。设备树这东西,配置对了就是对了,配置错了报错信息又往往不直接,所以把验证过的配置沉淀下来,是长期做点屏这件事最省力的方式。