1. 项目背景与核心价值
双屏异触技术在工业控制、商业展示和教育培训领域有着广泛的应用前景。RK3568作为瑞芯微推出的中高端ARM处理器,搭载四核Cortex-A55架构,主频可达2GHz,配合Mali-G52 GPU,能够很好地支撑Android 11系统的图形处理需求。这个项目要实现的是在一块RK3568开发板上同时驱动两块触摸屏,并且实现两块屏幕可以独立响应触摸事件。
在实际项目中,我们经常遇到这样的需求场景:比如在餐饮POS系统中,一面屏幕面向顾客用于展示菜单和订单确认,另一面屏幕面向服务员用于操作后台;或者在教育平板中,老师端和学生端需要独立操作但又共享同一硬件平台。传统方案往往采用两套独立系统,成本高且数据同步困难。而通过RK3568实现的双屏异触方案,不仅硬件成本大幅降低,系统响应延迟也能控制在毫秒级。
2. 硬件架构设计要点
2.1 显示接口选型与配置
RK3568芯片原生支持双屏输出,但需要特别注意接口组合的兼容性。经过实测验证,以下两种组合方案最为稳定:
-
HDMI+LVDS组合:
- HDMI接口支持1080P@60Hz输出
- LVDS接口通过SN65LVDS84芯片转换,支持1366x768分辨率
- 优势:HDMI接口即插即用,LVDS适合工业屏
-
双MIPI-DSI组合:
- 需要外接两路MIPI转换芯片(如TC358775)
- 支持1920x1200@60Hz双屏输出
- 优势:节省板载空间,适合高分辨率需求
重要提示:硬件设计阶段必须确保两路显示接口使用独立的时钟域,避免信号干扰导致花屏。我们在初期样机中就遇到过因为共用PLL时钟导致第二屏间歇性闪烁的问题。
2.2 触摸屏接口方案
实现真正的双屏异触,关键在于触摸数据的独立采集和处理。推荐采用以下架构:
code复制[触摸屏1] --I2C1--> | RK3568 | --I2C2--> [触摸屏2]
(中断引脚GPIO3_12) (中断引脚GPIO3_15)
具体实现要点:
- 为每块触摸屏分配独立的I2C通道(I2C1和I2C2)
- 每块屏的中断引脚连接到不同的GPIO
- 在设备树中正确配置input子系统的参数
3. Android系统层适配
3.1 内核设备树配置
RK3568的DTS文件需要针对双屏进行特殊配置。以下是关键代码片段:
dts复制&dsi0 {
status = "okay";
ports {
port@1 {
reg = <1>;
dsi0_out: endpoint {
remote-endpoint = <&tc358775_in>;
};
};
};
};
&i2c1 {
status = "okay";
gt9xx@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
touchscreen-size-x = <1920>;
touchscreen-size-y = <1200>;
interrupt-parent = <&gpio3>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
};
};
&i2c2 {
status = "okay";
ft5x06@38 {
compatible = "edt,ft5x06";
reg = <0x38>;
touchscreen-size-x = <1366>;
touchscreen-size-y = <768>;
interrupt-parent = <&gpio3>;
interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
};
};
3.2 Input子系统事件处理
Android系统通过EventHub监听输入设备事件。我们需要确保两个触摸屏生成不同的设备ID:
cpp复制// 在frameworks/native/services/inputflinger/EventHub.cpp
static bool isTouchScreenDevice(int32_t deviceId) {
// 为第二个触摸屏添加特殊判断
if (deviceId == SECOND_TOUCH_DEVICE_ID) {
return true;
}
// 原有判断逻辑...
}
4. 应用层实现方案
4.1 多Display管理
在Android 11中,可以通过DisplayManager获取所有Display对象:
java复制DisplayManager dm = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = dm.getDisplays();
for (Display display : displays) {
if (display.getDisplayId() != Display.DEFAULT_DISPLAY) {
// 创建针对第二屏的Window
Presentation presentation = new SecondaryScreen(context, display);
presentation.show();
}
}
4.2 触摸事件路由控制
实现触摸事件精准路由的关键在于重写Activity的dispatchTouchEvent方法:
java复制@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int displayId = event.getDisplayId();
if (displayId == SECOND_DISPLAY_ID) {
// 第二屏触摸事件处理
return handleSecondaryTouch(event);
} else {
// 主屏触摸事件处理
return super.dispatchTouchEvent(event);
}
}
5. 性能优化实战
5.1 触摸延迟优化
通过调整RK3568的CPU调度策略可以显著降低触摸延迟:
bash复制# 设置触摸中断处理的CPU亲和性
echo 2 > /proc/irq/$(cat /proc/interrupts | grep -m 1 gt9xx | awk '{print $1}' | sed 's/://')/smp_affinity
echo 4 > /proc/irq/$(cat /proc/interrupts | grep -m 1 ft5x06 | awk '{print $1}' | sed 's/://')/smp_affinity
# 调整CPU调频策略
echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
5.2 内存带宽分配
在rk3568.dtsi中调整内存控制器参数:
dts复制&dmc {
system-status-freq = <
/* 双屏工作时提升DDR频率 */
SYSTEM_STATUS_DUAL_DISPLAY 928000
>;
};
6. 常见问题排查指南
6.1 第二屏触摸无响应
排查步骤:
- 检查
dmesg | grep -i touch是否有驱动加载错误 - 使用
getevent -l命令查看原始输入事件 - 确认
/dev/input/eventX设备权限为0666
6.2 双屏显示不同步
解决方案:
- 在uboot阶段设置显示时序参数:
code复制setenv bootargs ... drm_kms_helper.edid_firmware=HDMI-A-1:edid/1920x1080.bin,DSI-1:edid/1280x800.bin - 检查两路显示通道的clock是否冲突
7. 量产测试方案
为确保双屏异触功能的稳定性,建议采用自动化测试方案:
-
触摸精度测试:
python复制import uiautomator2 as u2 d1 = u2.connect(ip1) # 主屏 d2 = u2.connect(ip2) # 副屏 d1.swipe_points([(100,200), (300,400)], 0.1) d2.swipe_points([(50,150), (250,350)], 0.1) -
压力测试脚本:
bash复制# 模拟双屏持续操作 while true; do input tap $((RANDOM%1920)) $((RANDOM%1200)) 1 & input tap $((RANDOM%1366)) $((RANDOM%768)) 2 & sleep 0.05 done
在实际项目中,我们通过这套方案实现了<20ms的触摸延迟,双屏触摸准确率达到99.8%以上。特别是在餐饮行业订单系统中,服务员和顾客可以同时操作不同界面,大幅提升了点餐效率。