
回复
openharmony 5.0.0
1.drm内核态驱动ok,modetest atomic测试通过,详细请参考
2.芯片 gpu 内核态驱动ok
调试display hdi代码过程中,手动执行render_service命令拉起render_service服务。openharmony图像起来之后再回退补丁。这样就不会因为display部分没写好导致机器重启了。
这样也方便编display hdi的库,然后手动推进去,这样就不用重复编固件调试了
--- a/foundation/graphic/graphic_2d/graphic.cfg 2025-05-23 17:54:58.080877485 +0800
+++ b/foundation/graphic/graphic_2d/graphic.cfg 2025-05-23 17:54:42.130878310 +0800
@@ -24,7 +24,7 @@
"services" : [{
"name" : "render_service",
"path" : ["/system/bin/render_service"],
- "critical" : [1, 5, 60],
+ "critical" : [0, 0, 60],
"importance" : -20,
"uid" : "graphics",
"gid" : ["system", "tp_host", "data_reserve"],
--- a/vendor/xxxx/xxxx/security_config/critical_reboot_process_list.json 2025-08-20 19:38:54.726204891 +0800
+++ b/vendor/xxxx/xxxx/security_config/critical_reboot_process_list.json 2025-08-14 18:07:51.455150508 +0800
@@ -18,7 +18,7 @@
},
{
"name": "render_service",
- "critical": [1, 5, 60]
+ "critical": [0, 0, 60]
},
{
"name": "storage_daemon",
由于技巧1中选择了render_service手动执行,有时候会占用一个调试串口。
--- a/vendor/xxxx/xxxx/etc/para/hardware_xxxx.para 2025-08-14 18:45:28.000000000 +0800
+++ b/vendor/xxxx/xxxx/etc/para/hardware_xxxx.para 2025-08-22 11:39:48.650294809 +0800
@@ -17,3 +17,7 @@
const.product.manufacturer=xxxx
const.product.software.version=xxxx
const.product.oharm.version=xxxx
+persist.hdc.mode=tcp
+persist.hdc.mode.usb=enable
+persist.hdc.mode.tcp=enable
+persist.hdc.port=55555
\ No newline at end of file
有时候因为屏幕亮屏策略没调好的原因导致调试出现问题,调试display hdi的时候最好在源码里面设置屏幕常亮。
--- a/base/powermgr/power_manager/services/native/include/power_state_machine.h 2024-12-18 17:43:37.223539366 +0800
+++ b/base/powermgr/power_manager/services/native/include/power_state_machine.h 2024-12-24 19:25:31.256451651 +0800
@@ -30,7 +30,7 @@
#include "hibernate_controller.h"
#endif
-#define DEFAULT_DISPLAY_OFF_TIME 30000
+#define DEFAULT_DISPLAY_OFF_TIME -1
#define DEFAULT_SLEEP_TIME 5000
namespace OHOS {
--- a/base/powermgr/power_manager/services/native/profile/power_mode_config.xml 2024-12-18 17:43:37.223539366 +0800
+++ b/base/powermgr/power_manager/services/native/profile/power_mode_config.xml 2024-12-24 19:29:29.116384104 +0800
@@ -32,7 +32,7 @@
-->
<switch_proxy version="1">
<proxy id="600">
- <switch id="101" value="30000" recover_flag="0"/>
+ <switch id="101" value="-1" recover_flag="0"/>
<switch id="102" value="0" recover_flag="0"/>
<switch id="103" value="-1" recover_flag="0"/>
<switch id="107" value="1" recover_flag="0"/>
display hdi编写一共有两种策略
笔者建议是,先基于模板来适配,亮屏成功后,参考3568的来增加对多屏的处理,还有热插拔逻辑。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
// 将连接器类型转换为可读字符串
const char* connector_type_to_string(uint32_t type) {
switch (type) {
case DRM_MODE_CONNECTOR_Unknown: return "Unknown";
case DRM_MODE_CONNECTOR_VGA: return "VGA";
case DRM_MODE_CONNECTOR_DVII: return "DVI-I";
case DRM_MODE_CONNECTOR_DVID: return "DVI-D";
case DRM_MODE_CONNECTOR_DVIA: return "DVI-A";
case DRM_MODE_CONNECTOR_Composite: return "Composite";
case DRM_MODE_CONNECTOR_SVIDEO: return "S-Video";
case DRM_MODE_CONNECTOR_LVDS: return "LVDS";
case DRM_MODE_CONNECTOR_Component: return "Component";
case DRM_MODE_CONNECTOR_9PinDIN: return "9-pin DIN";
case DRM_MODE_CONNECTOR_DisplayPort: return "DisplayPort";
case DRM_MODE_CONNECTOR_HDMIA: return "HDMI-A";
case DRM_MODE_CONNECTOR_HDMIB: return "HDMI-B";
case DRM_MODE_CONNECTOR_TV: return "TV";
case DRM_MODE_CONNECTOR_eDP: return "eDP";
case DRM_MODE_CONNECTOR_VIRTUAL: return "Virtual";
case DRM_MODE_CONNECTOR_DSI: return "DSI";
default: return "Unknown";
}
}
// 将连接状态转换为可读字符串
const char* connection_status_to_string(uint32_t status) {
switch (status) {
case DRM_MODE_CONNECTED: return "Connected";
case DRM_MODE_DISCONNECTED: return "Disconnected";
case DRM_MODE_UNKNOWNCONNECTION: return "Unknown";
default: return "Invalid";
}
}
// 扫描已连接的显示器
int scan_connected_displays(int fd) {
drmModeResPtr resources;
int i;
// 获取DRM资源(连接器、CRTC、编码器等)
resources = drmModeGetResources(fd);
if (!resources) {
fprintf(stderr, "Failed to get DRM resources\n");
return -1;
}
printf("Scanning connected displays...\n");
printf("Found %d connectors, %d CRTCs, %d encoders\n",
resources->count_connectors, resources->count_crtcs, resources->count_encoders);
// 遍历所有连接器(通常对应物理显示接口)
for (i = 0; i < resources->count_connectors; i++) {
drmModeConnectorPtr connector = drmModeGetConnector(fd, resources->connectors[i]);
if (!connector) {
fprintf(stderr, "Failed to get connector %d\n", resources->connectors[i]);
continue;
}
printf("\nConnector %d: %s, Status: %s\n",
connector->connector_id,
connector_type_to_string(connector->connector_type),
connection_status_to_string(connector->connection));
printf(" Encoder ID: %d\n", connector->encoder_id);
printf(" Modes available: %d\n", connector->count_modes);
// 获取当前活动的编码器和CRTC信息
if (connector->encoder_id) {
drmModeEncoderPtr encoder = drmModeGetEncoder(fd, connector->encoder_id);
if (encoder) {
printf(" Encoder CRTC ID: %d\n", encoder->crtc_id);
printf(" Encoder type: %d\n", encoder->encoder_type);
if (encoder->crtc_id) {
printf(" Active CRTC ID: %d\n", encoder->crtc_id);
// 获取CRTC(CRT控制器)的详细信息
drmModeCrtcPtr crtc = drmModeGetCrtc(fd, encoder->crtc_id);
if (crtc) {
printf(" CRTC mode: %s\n", crtc->mode_valid ? crtc->mode.name : "Invalid");
printf(" CRTC position: %dx%d\n", crtc->x, crtc->y);
drmModeFreeCrtc(crtc);
}
} else {
printf(" No active CRTC assigned to encoder\n");
}
drmModeFreeEncoder(encoder);
} else {
printf(" Failed to get encoder %d\n", connector->encoder_id);
}
} else {
printf(" No encoder assigned to connector\n");
}
drmModeFreeConnector(connector);
}
drmModeFreeResources(resources);
return 0;
}
int main() {
int fd;
uint64_t has_dumb;
// 打开DRM设备(通常第一个显卡是card0)
fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
if (fd < 0) {
fprintf(stderr, "Failed to open DRM device\n");
return 1;
}
// 检查是否支持dumb buffer功能(基本图形缓冲区管理)
if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || !has_dumb) {
fprintf(stderr, "DRM device does not support dumb buffers\n");
close(fd);
return 1;
}
// 扫描并显示连接的显示器信息
scan_connected_displays(fd);
close(fd);
return 0;
}
ohos_executable("modeset_crt_info") {
cflags_c = [
"-Wno-unused-variable",
]
sources = [
"modeset_atomic_crtc/modeset_crt_info.c",
]
deps = [
"//third_party/libdrm:libdrm",
]
install_images = [ "system" ]
install_enable = true
part_name = ""
subsystem_name = ""
}
运行效果(rk3568):
详细列出了当前系统检测到的显示连接器和其配置状态,可以查看每个显示器是否被分配了CRTC和Encoder。 在调试display的时候,可以用此程序来查看显示器是否激活