在嵌入式Linux系统的启动过程中,默认的文本启动日志往往缺乏良好的用户体验。为了提升设备启动时的视觉效果,可以通过 psplash 工具实现图形化开机动画,支持静态logo或动态动画显示。
psplash 是一个轻量级的启动屏幕程序,专为嵌入式Linux系统设计,具有以下核心特性:
1. 轻量高效:专为嵌入式设备设计,资源占用极低。
2. 图形化支持:支持静态图片或动态帧动画(通过快速切换连续图片实现)。
3. 高度可定制:可配置启动图像、进度条样式、显示时间等参数。
4. 跨平台兼容:支持多种嵌入式Linux发行版和硬件平台。
注:本次在ELF 2(RK3588)平台主要验证静态图片显示和动态logo动画功能,进度条功能暂未测试。
下文将详细介绍如何在ELF 2(RK3588)5.10.209 Buildroot系统中配置psplash,实现自定义开机动画。
一、图片制作
1. 创建工程文件夹
首先,我们需要在虚拟机中创建一个文件夹来保存相关工程文件。打开终端,执行以下命令:
elf@ubuntu:~$ mkdir -p psplash_logo/mp4_logo/
接着,将源码中的 logo.mp4 视频拷贝到刚刚创建的 mp4_logo 文件夹中。
2. 安装 FFmpeg
为了后续处理 MP4 视频,我们需要安装 FFmpeg。在终端中执行以下命令:
elf@ubuntu:~$ cd psplash_logo/mp4_logo/
elf@ubuntu:~/psplash_logo/mp4_logo$ sudo apt-get update
elf@ubuntu:~/psplash_logo/mp4_logo$ sudo apt-get install ffmpeg
3. 创建图片存储文件夹
创建一个名为 part0 的文件夹,用于存储后续生成的图片:
elf@ubuntu:~/psplash_logo/mp4_logo$ mkdir part0
4. 提取视频帧为图片
使用 FFmpeg 将视频文件 logo.mp4 按每秒 7 帧(7fps)的速率提取为一系列连续的 PNG 图片,并保存到 part0/ 目录下。执行以下命令:
elf@ubuntu:~/psplash_logo/mp4_logo$ ffmpeg -i logo.mp4 -f image2 -r 7 part0/%04d.png
5. 查看生成的图片
执行以下命令查看 part0 文件夹中的图片内容:
elf@ubuntu:~/psplash_logo/mp4_logo$ ls part0/
0001.png 0004.png 0007.png 0010.png 0013.png 0016.png 0019.png 0022.png 0025.png 0028.png 0031.png 0034.png 0037.png 0040.png 0043.png 0046.png 0049.png 0052.png
0002.png 0005.png 0008.png 0011.png 0014.png 0017.png 0020.png 0023.png 0026.png 0029.png 0032.png 0035.png 0038.png 0041.png 0044.png 0047.png 0050.png 0053.png
0003.png 0006.png 0009.png 0012.png 0015.png 0018.png 0021.png 0024.png 0027.png 0030.png 0033.png 0036.png 0039.png 0042.png 0045.png 0048.png 0051.png 0054.png
二、图片转换
1. 检查图片分辨率
在将图片转换为 .h 文件之前,需要确保图片分辨率与屏幕分辨率一致。使用以下命令查看图片分辨率:
elf@ubuntu:~/psplash_logo/mp4_logo$ file part0/0001.png
part0/0001.png: PNG image data, 640 x 360, 8-bit/color RGB, non-interlaced
可以看到图片分辨率是640x360,本次测试使用的是飞凌 7 寸 MIPI 屏,分辨率为 1024x600,因此需要对图片进行分辨率转换。
2. 创建相关文件夹
创建 logo_h 文件夹,并在其中分别创建 h、logo_1024x600、master 三个文件夹:
elf@ubuntu:~/psplash_logo/mp4_logo$ mkdir logo_h
elf@ubuntu:~/psplash_logo/mp4_logo$ cd logo_h/
elf@ubuntu:~/psplash_logo/mp4_logo/logo_h$ mkdir h logo_1024x600 master
3. 拷贝图片到 master 文件夹
将 part0 文件夹下的所有 PNG 格式的图片拷贝到 master 文件夹中备用:
elf@ubuntu:~/psplash_logo/logo_h$ cp ../part0/* ./master/
4. 创建分辨率转换脚本
在 master 文件夹中创建 fix_1024x600.sh 脚本,用于进行分辨率转换。执行以下命令创建脚本:
elf@ubuntu:~/psplash_logo/mp4_logo/logo_h$ cd master/
elf@ubuntu:~/psplash_logo/mp4_logo/logo_h/master$ vi fix_1024x600.sh
脚本内容如下:
#!/bin/bash
for img in *.png; do
convert "$img" -resize 1024x600! "../logo_1024x600/$img"
done
5. 赋予脚本可执行权限
执行以下命令赋予脚本可执行权限:
elf@ubuntu:~/psplash_logo/logo_h/master$ chmod +x fix_1024x600.sh
6. 执行脚本
执行脚本进行分辨率转换:
elf@ubuntu:~/psplash_logo/logo_h/master$ ./fix_1024x600.sh
7. 验证转换结果
执行完毕后,使用以下命令查看 logo_1024x600 文件夹下转换好的图片文件的分辨率:
elf@ubuntu:~/psplash_logo/mp4_logo/logo_h/master$ file ../logo_1024x600/0001.png
../logo_1024x600/0001.png: PNG image data, 1024 x 600, 8-bit/color RGB, non-interlaced
8. 创建生成 .h 文件的脚本
在 h 文件夹中新建 make-image-header.sh 脚本,用于将图片转换为 .h 文件。执行以下命令创建脚本:
elf@ubuntu:~/psplash_logo/mp4_logo/logo_h/master$ cd ../h/
elf@ubuntu:~/psplash_logo/mp4_logo/logo_h/h$ vi make-image-header.sh
脚本内容如下:
#!/bin/sh
# 指定图片目录和名称前缀
img_dir="$1"
name_prefix="$2"
# 检查目录是否存在
if [ ! -d "$img_dir" ]; then
echo "目录 $img_dir 不存在"
exit 1
fi
i=0
# 遍历目录中的所有 PNG 文件
for img in "$img_dir"/*.png; do
# 检查是否找到了 PNG 文件
if [ ! -e "$img" ]; then
echo "没有找到 PNG 文件"
break
fi
imageh=`basename "$img" .png`-img.h
# name="${name_prefix}_${imageh}"
name="${name_prefix}_$(printf "%01d" "$i")_IMG"
# 生成 C 头文件
gdk-pixbuf-csource --macros "$img" > "$imageh.tmp"
sed -e "s/MY_PIXBUF/${name}/g" -e "s/guint8/uint8/g" "$imageh.tmp" > "$imageh" && rm "$imageh.tmp"
i=$(expr $i + 1)
echo "生成了 $imageh"
done
9. 赋予脚本可执行权限
执行以下命令赋予脚本可执行权限:
elf@ubuntu:~/psplash_logo/logo_h/h$ chmod +x make-image-header.sh
10. 执行脚本
执行脚本将图片转换为 .h 文件:
elf@ubuntu:~/psplash_logo/logo_h/h$ ./make-image-header.sh ../logo_1024x600 POKY
生成了 0001-img.h
生成了 0002-img.h
生成了 0003-img.h
生成了 0004-img.h
生成了 0005-img.h
生成了 0006-img.h
生成了 0007-img.h
生成了 0008-img.h
生成了 0009-img.h
生成了 0010-img.h
生成了 0011-img.h
生成了 0012-img.h
...
...
...
三、psplash源码修改
1. 拷贝并解压 psplash 源码
请自行将 psplash 源码拷贝到 psplash_logo/ 文件夹中并解压。
elf@ubuntu:~/psplash_logo$ ls
mp4_logo psplash.zip
elf@ubuntu:~/psplash_logo$ unzip psplash.zip
2. 修改 Makefile 文件
修改 Makefile 文件,将 CC 变量修改为 ELF 2 平台使用的交叉编译器。打开 Makefile 文件,修改内容如下:
AUTOMAKE = ${SHELL} /home/wonhere/zhangqi/OMAP3530/psplash/missing --run automake-1.11
AWK = gawk
#CC = arm-none-linux-gnueabi-gcc
CC = /home/elf/aarch64-buildroot-linux-gnu_sdk-buildroot/bin/aarch64-linux-gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = arm-none-linux-gnueabi-gcc -E
3. 创建 logo 文件夹并拷贝 .h 文件
创建 logo 文件夹,并将 h 文件夹中的 *-img.h 文件都拷贝到 logo 文件夹中:
elf@ubuntu:~/psplash_logo$ mkdir logo
elf@ubuntu:~/psplash_logo$ cp mp4_logo/logo_h/h/* logo/
4. 在 psplash.c 文件中添加引用
在 psplash.c 文件中添加对 .h 文件的引用:
#include "logo/0001-img.h"
#include "logo/0002-img.h"
#include "logo/0003-img.h"
。。。
。。。
。。。
#include "logo/0047-img.h"
#include "logo/0048-img.h"
#include "logo/0049-img.h"
#include "logo/0050-img.h"
#include "logo/0051-img.h"
#include "logo/0052-img.h"
#include "logo/0053-img.h"
#include "logo/0054-img.h"
5. 添加宏定义
添加宏定义,方便后续编写参数:
#define IMG_WIDTH(x) POKY_##x##_IMG_WIDTH
#define IMG_HEIGHT(x) POKY_##x##_IMG_HEIGHT
#define IMG_BYTES_PER_PIXEL(x) POKY_##x##_IMG_BYTES_PER_PIXEL
#define IMG_RLE_PIXEL_DATA(x) POKY_##x##_IMG_RLE_PIXEL_DATA
6. 在 main 函数中添加代码
在 main 函数中添加如下内容,用于绘制图片:
/* Draw the Myir logo */
/* psplash_fb_draw_image (fb,
(fb->width - POKY_IMG_WIDTH)/2,
((fb->height * 5) / 6 - POKY_IMG_HEIGHT)/2,
POKY_IMG_WIDTH,
POKY_IMG_HEIGHT,
POKY_IMG_BYTES_PER_PIXEL,
POKY_IMG_RLE_PIXEL_DATA);
*/
psplash_fb_draw_image (fb, (fb->width - IMG_WIDTH(0))/2, (fb->height - IMG_HEIGHT(0))/2,IMG_WIDTH(0),IMG_HEIGHT(0),IMG_BYTES_PER_PIXEL(0),IMG_RLE_PIXEL_DATA(0));
usleep(50000);
。。。
。。。
。。。
psplash_fb_draw_image (fb, (fb->width - IMG_WIDTH(0))/2, (fb->height - IMG_HEIGHT(0))/2,IMG_WIDTH(0),IMG_HEIGHT(0),IMG_BYTES_PER_PIXEL(0),IMG_RLE_PIXEL_DATA(50));
usleep(50000);
psplash_fb_draw_image (fb, (fb->width - IMG_WIDTH(0))/2, (fb->height - IMG_HEIGHT(0))/2,IMG_WIDTH(0),IMG_HEIGHT(0),IMG_BYTES_PER_PIXEL(0),IMG_RLE_PIXEL_DATA(51));
usleep(50000);
psplash_fb_draw_image (fb, (fb->width - IMG_WIDTH(0))/2, (fb->height - IMG_HEIGHT(0))/2,IMG_WIDTH(0),IMG_HEIGHT(0),IMG_BYTES_PER_PIXEL(0),IMG_RLE_PIXEL_DATA(52));
usleep(50000);
psplash_fb_draw_image (fb, (fb->width - IMG_WIDTH(0))/2, (fb->height - IMG_HEIGHT(0))/2,IMG_WIDTH(0),IMG_HEIGHT(0),IMG_BYTES_PER_PIXEL(0),IMG_RLE_PIXEL_DATA(53));
usleep(50000);
这里的 IMG_WIDTH 表示宽度,IMG_HEIGHT 表示高度,IMG_BYTES_PER_PIXEL 表示像素格式,IMG_RLE_PIXEL_DATA 表示图片数据。由于宽度、高度和像素格式都相同,因此使用相同的参数,仅修改 IMG_RLE_PIXEL_DATA 图片数据的参数。
7. 编译源码
执行以下命令进行编译:
elf@ubuntu:~/psplash_logo$ make
编译成功后,会在 psplash_logo 文件夹下生成 psplash 和 psplash-write 文件。将这两个文件通过 U 盘拷贝到 ELF 2 开发板的 /usr/bin/ 目录。
四、Linux系统配置
1. 创建启动脚本
在 ELF 2 开发板的 /etc/init.d/ 目录下新建 S50weston_psplash 脚本:
root@elf2-buildroot:~# vi /etc/init.d/S50weston_psplash
2. 编写脚本内容
脚本内容如下:
#!/bin/sh
### BEGIN INIT INFO
# Provides: psplash
# Required-Start:
# Required-Stop:
# Default-Start: S
# Default-Stop:
### END INIT INFO
sleep 1
/etc/init.d/S49weston stop
case "$1" in
start)
echo "Starting psplash..."
export TMPDIR=/mnt/.psplash
mkdir -p $TMPDIR
mount tmpfs -t tmpfs $TMPDIR -o,size=2M
rotation=0
if [ -e /etc/rotation ]; then
read rotation < /etc/rotation
fi
/usr/bin/psplash --angle $rotation &
;;
stop)
echo "Stopping psplash..."
killall psplash
umount $TMPDIR
rmdir $TMPDIR
;;
*)
echo "Usage: \$0 {start|stop}"
exit 1
;;
esac
sleep 6
pkill psplash
/etc/init.d/S49weston start
/etc/init.d/S50matrix-browser start
exit 0
3. 赋予脚本可执行权限
执行以下命令赋予脚本可执行权限:
root@elf2-buildroot:~# chmod +x /etc/init.d/S50weston_psplash
4. 注意事项
sleep 6 这里要根据实际的播放时间进行配置。建议在动画播放到最后放一张黑色背景的图片,以防关机时看到最底层的动态 logo 图片。
五、验证效果
配置完成后,保存并重启开发板,即可看到自定义的开机动画。
|
|