RK3399的HDMI双屏异显的有关问题
背景
- Platform: RK3399
- OS: Android7.1.2
- Kernel: v4.4.103
问题及原因分析
项目中,我们使用Presentation
开发了双屏异显功能。
不稳定问题
- 在测试中,发现开机上电HDMI有时候有显示,有时候又没有,有时候甚至会一闪一闪的
后面发现是硬件HPD脚不稳定,导致HDMI显示时好时坏。HPD为高时,主控才会通过DDC去读EDID。异显内容覆盖问题
- 要显示在HDMI上的异显内容,覆盖显示在了本地的MIPI屏上,非必现。
代码中,我们先调用了DisplayManager
的getDisplays()
获取屏幕的数量,只有2个才会调用Presentation
去呈现异显内容。但因为上面的原因导致屏幕数量获取错误,从而出现了这个问题。
后面我们改用使用广播监听的方式去检测HDMI的热插拔状态,而且硬件也修改,但获取的屏幕数量还是不对,
最后我们使用DisplayManager.DisplayListener
的onDisplayAdded
和onDisplayRemoved
来监听屏幕的变化,监听到变化之后再调用getDisplays()
方法来获取准确的屏幕信息,包括数量、Name等。使用广播的方式去监听热插拔然后马上去获取屏幕数量,可能这个时候HDMI还没有ready。
扩展
驱动代码
主要驱动代码:
dw-hdmi.c
: HDMI驱动,包括内部I2C接口实现drm_edid.c
: edid相关dw_hdmi-rockchip.c
: drm框架部分
插拔是否成功可以在check_hdmi_irq()@dw-hdmi.c
中打印log
HDMI热插拔状态检测
比较常用的广播监听
注册一个动态广播来获取HDMI接口的插拔,它的Action的name为 “android.intent.action.HDMI_PLUGGED”,具体的代码如下:
private static BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent receivedIt) {
String action = receivedIt.getAction();
if (action.equals("android.intent.action.HDMI_PLUGGED")) {
boolean state = receivedIt.getBooleanExtra("state", false);
if (state) {
isHdmiConnect = true;
} else {
isHdmiConnect = false;
}
}
}
};
直接获取状态:
通过直接读取:/sys/devices/virtual/switch/hdmi/state
private static boolean isHdmiSwitchSet() {
// The file '/sys/devices/virtual/switch/hdmi/state' holds an int -- if it's 1 then an HDMI device is connected.
// An alternative file to check is '/sys/class/switch/hdmi/state' which exists instead on certain devices.
File switchFile = new File("/sys/devices/virtual/switch/hdmi/state");
if (!switchFile.exists()) {
switchFile = new File("/sys/class/switch/hdmi/state");
}
try {
Scanner switchFileScanner = new Scanner(switchFile);
int switchValue = switchFileScanner.nextInt();
switchFileScanner.close();
return switchValue > 0;
} catch (Exception e) {
return false;
}
}
但不能频繁操作
调试相关
/sys/class/drm/card0-HDMI-A-1
- 设置drm的调试log等级:
一般设置为如下值:sys结点位置: /sys/module/drm/parameters/debug debug:Enable debug output, where each bit enables a debug category. Bit 0 (0x01) will enable CORE messages (drm core code) Bit 1 (0x02) will enable DRIVER messages (drm controller code) Bit 2 (0x04) will enable KMS messages (modesetting code) Bit 3 (0x08) will enable PRIME messages (prime code) Bit 4 (0x10) will enable ATOMIC messages (atomic code) Bit 5 (0x20) will enable VBL messages (vblank code) (int) 示例: echo 0x0c > /sys/module/drm/parameters/debug 打开了KMS, PRIME这些的打印, kernel驱动中使用DRM_DEBUG_KMS和 DRM_DEBUG_PRIME打印的信息都可以打印出来
echo 0x1f > /sys/module/drm/parameters/debug
- 查看EDID有没有识别
dmesg | grep drm
- 查看HDMI的状态
cat /d/dw-hdmi/status
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DD'Notes!
评论