如何在单台显示器上禁用启动画面,

如何在单台显示器上禁用启动画面,

我的堆栈是:raspberrypi、uboot、buildroot 和 weston。我有两个显示设备连接到主板。第一个是用户界面的触摸屏(HDMI-A-1),第二个是投影仪的触摸屏(HDMI-A-2)。我使用自定义内核启动徽标。是否可以仅在上显示启动启动画面HDMI-A-1?我设法通过在 bootargs 中禁用来做到这一点HDMI-A-2,如下所示:

bootargs=console=ttyAMA0,115200 earlycon=ttyAMA0,115200 splash video=HDMI-A-1:1024x600-32 video=HDMI-A-2:d vt.global_cursor_default=0

但后来我无法HDMI-A-2在运行时打开:

connector[89]: HDMI-A-1
        crtc=crtc-0
        self_refresh_aware=0
connector[153]: HDMI-A-2
        crtc=(null)
        self_refresh_aware=0

有什么解决办法吗?

编辑:

我发现通过将帧缓冲区映射到控制台可以部分实现这一点:

fbcon=map:1

文档

它仅在两个显示器都有单独的帧缓冲区的情况下才有效。不幸的是,vc4 为两个显示器发布了一个共享的帧缓冲区,所以这对我来说不是一个解决方案。

编辑2:

不幸的是,据我所知,如果不修补内核,这是不可能的。有 raspberrypi 固件可以做到这一点,但它只能在 32 位系统上编译。RaspberryPi 固件开发人员强烈声称没有 64 位端口,他们未来也没有这样做的计划。

关联: https://github.com/raspberrypi/firmware/issues/550

答案1

正如我在评论中提到的,可以使用 DRM 创建虚拟帧缓冲区。

  1. 在 *.h 文件中准备适当分辨率的徽标。这可能会有所帮助:https://lvgl.io/tools/imageconverter

  2. 我们需要编写简单的 C 程序:

a)包括第一步中的徽标:

#include "logo.h"

b)我们需要它通过 ioctl 调用 drm:

#include <sys/ioctl.h>
#include <drm/drm.h>
#include <drm/drm_mode.h>

c) 打开适当的设备:

int dri_fd0  = open("/dev/dri/card0",O_RDWR | O_CLOEXEC);

d)从 drm 检索信息:

struct drm_mode_modeinfo conn_mode_buf[20]={0};
    uint64_t    conn_prop_buf[20]={0},
                conn_propval_buf[20]={0},
                conn_enc_buf[20]={0};

    struct drm_mode_get_connector conn={0};

    conn.connector_id=res_conn_buf[i];

    ioctl(dri_fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn);
    conn.modes_ptr=(uint64_t)conn_mode_buf;
    conn.props_ptr=(uint64_t)conn_prop_buf;
    conn.prop_values_ptr=(uint64_t)conn_propval_buf;
    conn.encoders_ptr=(uint64_t)conn_enc_buf;
    ioctl(dri_fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn);

e) 初始化虚拟缓冲区:struct drm_mode_create_dumb create_dumb={0}; struct drm_mode_map_dumb map_dumb={0}; struct drm_mode_fb_cmd cmd_dumb={0};

create_dumb.width = width;
create_dumb.height = height;

create_dumb.bpp = 32;
create_dumb.flags = 0;
create_dumb.pitch = 0;
create_dumb.size = 0;
create_dumb.handle = 0;
ioctl(dri_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);

cmd_dumb.width=create_dumb.width;
cmd_dumb.height=create_dumb.height;
cmd_dumb.bpp=create_dumb.bpp;
cmd_dumb.pitch=create_dumb.pitch;
cmd_dumb.depth=24;
cmd_dumb.handle=create_dumb.handle;
ioctl(dri_fd,DRM_IOCTL_MODE_ADDFB,&cmd_dumb);

map_dumb.handle=create_dumb.handle;
ioctl(dri_fd,DRM_IOCTL_MODE_MAP_DUMB,&map_dumb);

fb_base[i] = mmap(0, create_dumb.size, PROT_READ | PROT_WRITE, MAP_SHARED, dri_fd, map_dumb.offset);

struct drm_mode_get_encoder enc={0};

enc.encoder_id=conn.encoder_id;
ioctl(dri_fd, DRM_IOCTL_MODE_GETENCODER, &enc); //get encoder

struct drm_mode_crtc crtc={0};

crtc.crtc_id=enc.crtc_id;
ioctl(dri_fd, DRM_IOCTL_MODE_GETCRTC, &crtc);

crtc.fb_id=cmd_dumb.fb_id;
crtc.set_connectors_ptr=(uint64_t)&res_conn_buf[i];
crtc.count_connectors=1;
crtc.mode=conn_mode_buf[0];
crtc.mode_valid=1;
ioctl(dri_fd, DRM_IOCTL_MODE_SETCRTC, &crtc);

f)将带有您的徽标的数据从 c 数组复制到视频卡共享缓冲区:

memcpy(fb_base[0], uint32_data, sizeof(uint32_t) * logo_width * logo_height);

我们需要循环执行此操作,因为缓冲区会定期自动清除。

  1. 为专用平台构建应用程序并复制到/usr/bin/

  2. 添加触发器udev:a)在 /usr/lib/udev/rules.d/11-framebuffer.rules 中创建新文件

KERNEL=="card0", RUN+="/usr/bin/splash-launch"b)在文件内部添加触发器,当视频卡准备就绪时调用启动画面:

相关内容