Blog:
Linux 开机动画

Monday, June 21, 2021

开机动画普遍存在于消费类电子设备,特别是手机和平板。嵌入式 Linux 系统除了显示开机 logo 外,同样也可以实现开机动画。本文将在 Colibri iMX8X 计算机模块上介绍如何添加自定义的开机动画。

嵌入式设备从上电开机,会经历系统初始化、驱动加载、运行应用,最终在屏幕上显示应用界面。这个过程取决于嵌入式系自身的复杂程度和应用程序,通常可以从几秒到几十秒不等。而期间显示开机进度条或者开机动画能够提升设备的使用体验。文件接下会演示如何使用 PSplash 实现进度条显示,EasySplash 实现内容更加丰富的开机动画。

PSplash

这是一个非常精简的工具,极少的第三方软件依赖,首次发布于 2006 年。同时它能够非常容易地集成到  Yocto Project 中,事实上在 Toradex 默认的 Yocto Project 环境中已经包含了相应的 recipe。用户只要在 local.conf 中添加 IMAGE_INSTALL_append = " psplash" 即看到默认的开机进度条。但正由于其精简的特定,任何的修改包括背景图片、颜色都需要通过直接更改头文件,甚至是源代码来完成。在 Yocto Project 中这就需要编写相应的补丁文件。对于简单的图片更改,这会是更加耗时的操作。因此我们接下来使用 Yocto Project 生成的 SDK 直接编译 PSplash。


首先下载PSplash 源码。

$ git clone git://git.yoctoproject.org/psplash


准备一张和显示屏像素一致的背景图片,格式为 jpg。以及合适尺寸的进度条图片,同样也是 jpg 格式。这里我们使用 7寸 RGB 并口 LCD 显示屏,像素为 800x480。背景图片和进度条图片分别为 toradex.jpg 和 bar.jpg。将图片放在 PSplash 源码目录中。

然后使用psplash 自带的 make-image-header.sh 将图片转换为头文件。

$ cd psplash
$ ./make-image-header.sh bar.jpg BAR
$ ./make-image-header.sh toradex.jpg POKY


此时会生成 bar.jpg-img.h 和 toradex.jpg-img.h 两个文件。为了编译方便,分别将其重命名为 psplash-bar-img.h 和 psplash-poky-img.h,否则需要修改 psplash.c 包含新生成的头文件。

psplash-config.h 和 psplash-colors.h 两个文件中可以修改显示效果和颜色。例如在 psplash-config.h 中我们使用全屏显示。

/* Bool indicating if the image is fullscreen, as opposed to split screen */
#ifndef PSPLASH_IMG_FULLSCREEN
#define PSPLASH_IMG_FULLSCREEN 1
#endif


在  psplash-colors.h 中将默认背景颜色设置为黑色,和上面背景图片的色彩一致。进度条则为蓝色。

/* This is the overall background color */
#define PSPLASH_BACKGROUND_COLOR 0x00,0x00,0x00

/* This is the color of any text output */
#define PSPLASH_TEXT_COLOR 0x6d,0x6d,0x70

/* This is the color of the progress bar indicator */
#define PSPLASH_BAR_COLOR 0x17,0x17,0xde

/* This is the color of the progress bar background */
#define PSPLASH_BAR_BACKGROUND_COLOR 0xec,0xec,0xe1


配置修改完成后,使用 SDK 进行编译。

$ source ~/SDK/environment-setup-aarch64-tdx-linux
$ aclocal
$ autoheader
$ automake –add-missing
$ autoconf
$ ./configure
$ make


编译好后,将 psplash 和 psplash-systemd 两个可执行程序复制到安装了 Linux Reference Minimal V5.3.0 BSP 的 Colibri iMX8X,路径为 /usr/bin/。同时在 /lib/systemd/system 创建下面两个 systemd service 文件,用于 psplash 自启动。

  • psplash-start.service

[Unit]
Description=Start psplash boot splash screen
DefaultDependencies=no
RequiresMountsFor=/run

[Service]
Type=notify
ExecStart=/usr/bin/psplash
RemainAfterExit=yes

[Install]
WantedBy=sysinit.target


  • psplash-systemd.service

[Unit]|
Description=Start psplash-systemd progress communication helper|
DefaultDependencies=no
After=psplash-start.service|
Requires=psplash-start.service
RequiresMountsFor=/run

[Service]
ExecStart=/usr/bin/psplash-systemd
RemainAfterExit=yes

[Install]
WantedBy=sysinit.target


然后执行

# systemctl enable psplash-start.service
# systemctl enable psplash-systemd.service


为了不在屏幕上显示启动日志信息,还需要在 u-boot 中配置以下参数。

setenv setupargs 'vt.global_cursor_default=0 consoleblank=0 console=${console}'
saveenv


重启后可以看到屏幕上显示的进度条。

 

EasySplash

借助 PSplash 可以实现简单的进度条显示,如果需要更加生动的开机动画,则可以使用 EasySplash。这是一个非常新的项目,在 2020 年正式发布首个版本。它基本原理是将一个视频文件逐帧拆为 PNG 图片,然后按照一定的帧率再依次显示。在最新的版本中,作者使用 Rust 重写了该项目,支持 gstreamer 直接播放视频文件。本文这里仍旧采用1.0.x 版本,使用图片方式显示开机动画。由于 EasySplash 需要借助一些第三方库如libpng,为了方便测试,Colibri iMX8X 将安装 Linux Multimedia BSP v5.3.0


首先下载 EasySplash 源码。

$ git clone -b 1.0.x https://github.com/OSSystems/EasySplash.git


编译 EasySplash。

$ source ~/SDK/environment-setup-aarch64-tdx-linux
$ cd EasySplash
$ mkdir build bin
$ cd build
$ cmake .. -DDISPLAY_TYPE_GLES=1 -DEGL_PLATFORM_VIV_FB=1 \
-DENABLE_SYSTEMD_SUPPORT=1 -DCMAKE_INSTALL_PREFIX=../bin
$ make DESTDIR=../bin
$ make DESTDIR=../bin install


编译完成后将 bin 目录中的 easysplash 和 easysplashctl 可执行二进制文件复制到  Colibri iMX8X 的 /sbin/ 中,easysplash-quit.service 和 easysplash-start.service 复制到 /lib/systemd/system 中。

接下来准备需要显示的开机动画文件。 EasySplash 会从 zip 压缩包读取动画播放控制文件和 PNG 图片,zip 压缩包中的内容如下:

$ tree -L 1 .
.
├── desc.txt
├── part1
└── part2


desc.txt 是动画播放控制文件,part1 和 part2 是两个文件夹,用于存放 PNG 图片。desc.txt 的内容如下,这里用于举例说明。

800 480 20
p 1 0 part1
p 1 0 part2
p 1 0 part1
p 1 0 part2


第一行分辨表示显示屏幕宽 800 像素,高 480 像素,以 20 fps 速度显示图片。第二行,p:播放模式,需要完整显示所有的内容后才停止,1:循环次数,0:该参数是遗留变量,不再被使用,part1:PNG 图片存放的位置。用户可以更具需要添加多行来显示其他内容。该文件的详细说明可以参考源码中 doc/Animation-Structure.md。

PNG 图片可以通过 ffmpeg 工具从视频文件获取。这里我们采用 EasySplash 自己的 ossystem-demo 中的 mp4 作为演示。

$ ffmpeg -i beginning.mp4 part1/demo1%04d.png
$ ffmpeg -i end.mp4 part1/demo2%04d.png


将生成的文件压缩为  bootanimation.zip,复制到  Colibri iMX8X 的 /home/root/ 目录。

$ zip -r0 bootanimation.zip desc.txt part1part2


修改 /lib/systemd/system 中  easysplash-start.service 文件,ExecStart 中修改  easysplash 实际存放的路径,同时添加  bootanimation.zip 所在的位置。

[Unit]
Description=Starts EasySplash Boot screen
Wants=systemd-vconsole-setup.service
After=systemd-vconsole-setup.service systemd-udev-trigger.service systemd-udevd.service
DefaultDependencies=no

[Service]
EnvironmentFile=-/default/easysplash
Type=notify
ExecStart=/sbin/easysplash -i /home/root/bootanimation.zip

[Install]
WantedBy=sysinit.target


easysplash-quit.service 也是一样。

[Unit]
Description=Terminate EasySplash Boot Screen
After=easysplash-start.service
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/sbin/easysplashctl 100 --wait-until-finished
TimeoutSec=30

[Install]
WantedBy=sysinit.target


然后执行

# systemctl enable  easysplash-start.service
# systemctl enable easysplash-quit.service


为了不在屏幕上显示启动日志信息,还需要在 u-boot 中配置以下参数。

setenv setupargs 'vt.global_cursor_default=0 consoleblank=0 console=${console}'
saveenv


重启后可以看到开机动画。


总结

上面介绍了在不改变 BSP 本身结构和应用程序的情况下添加开机进度条或者开机动画,所以这些工具都是用户应用而运行的。为了更早地显示开机动画,也有采用其他方式加载,例如 Torizon,它使用 initial ram disk,在其中运行 plymouth 显示开机动画,并且可以非常方便地对其进行替换。由于 initial ram disk 是在正式的 rootfs 前运行,这是一个非常精简的文件系统,从而能很早完成加载并示画面。Toradex Linux BSP 尚未采用该方式。另外对于需要快速启动的嵌入式设备,开机动画的运行不可避免会占用一部分系统资源,从而影响到主要应用的加载和运行。

Author: 胡珊逢,FAE,韬睿(上海)
Share this on:

Leave a comment

Please login to leave a comment!
Have a Question?