文章目录
- Yocto使用systemd设置开机自启动程序
- 一、 systemd介绍及service设置
- 二、yocto集成
Yocto使用systemd设置开机自启动程序
本篇文章为基于raspberrypi 4B单板的yocto实战系列的第七篇文章:
一、yocto 编译raspberrypi 4B并启动
二、yocto 集成ros2(基于raspberrypi 4B)
三、Yocto创建自定义的layer和image
四、Yocto创建静态IP和VLAN
五、Yocto集成QT5
六、Yocto给组件分组(packagegroups)
在第五章节的时候我们在rpi-robot的image中集成了qt5组件并且写了一个我们的qt demo程序而且成功在板子上运行,当时是设置了一些环境变量然后手动启动了这个例子,如果这个demo实际上就是我们产品的luncher,那么是不是应该开机以后就应该自动拉起这个程序呢,本章的内容我们就来介绍下怎么使用systemd的service来完成开机自启动这个功能。
一、 systemd介绍及service设置
Systemd 是 Linux 系统工具,用来启动守护进程,已成为大多数发行版的标准配置,它的设计目标是,为系统的启动和管理提供一套完整的解决方案。
- 常用的systemd systemctl操作指令:
启动某一个服务:
systemctl start <service_name>
停止服务:
systemctl stop <service_name>
重启服务:
systemctl restart <service_name>
查看服务状态:
systemctl status <service_name>
开机自启动一个服务:
systemctl enable <service_name>
禁用一个服务:
systemctl disable <service_name>
查看所有已经启用的服务:
systemctl list-unit-files --type=service | grep enabled
- 创建 systemd service 文件
要想使用systemd自启动服务我们首先需要有一个serivce,一般是一个以.service结尾的文件,比如rpi-robot-luncher.service,内容如下
[Unit]
Description=Initial RPI Robot Luncher
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/sbin/rpi_robot_init.sh
[Install]
WantedBy=multi-user.target
字段介绍:
- Description:描述服务的简短说明。
- After:指定在哪些系统单元之后启动服务。这里的 multi-user.target 是系统启动后进入多用户环境的目标,这意味着系统已经完成了基本的启动并准备好接受用户登录。
- ExecStart:指定要执行的脚本或命令的路径。
- Restart:指定服务退出后的重新启动策略,always 表示总是重新启动。
- WantedBy:指定服务的启动目标,通常设置为 multi-user.target,表示在多用户环境中启动。
这个service指定了一个启动脚本rpi_robot_init.sh,当这个service启动的时候就会执行这个脚本,我们把之前手动设置环境变量以及启动luncher的命令写到这个脚本里面:
#!/bin/sh
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_NO_LIBINPUT=1
qml_luncher
关于systemd的详解可以学习这篇文章: Systemd 入门教程
二、yocto集成
有了rpi-robot-luncher.service和rpi_robot_init.sh这两个文件就能完成我们自启动的目的,下一步就是在layer中找地方集成这两个文件到image中去。
- 创建recipes-core/systemd/rpi-robot-init文件夹和rpi-robot-init.bb文件
rpi-robot-init文件夹下存放rpi-robot-luncher.service和rpi_robot_init.sh
mkdir -p recipes-core/systemd/rpi-robot-init
touch recipes-core/systemd/rpi-robot-init.bb
rpi-robot-init.bb的内容如下:
DESCRIPTION = "The goal is to init rpi robot luncher"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
PV = "1.0"
SRC_URI = " file://rpi-robot-luncher.service \
file://rpi_robot_init.sh \
"
inherit systemd update-rc.d
SYSTEMD_PACKAGES += "${PN}"
SYSTEMD_SERVICE_${PN} = "rpi-robot-luncher.service"
SYSTEMD_AUTO_ENABLE_${PN} = "enable"
do_install() {
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
install -d ${D}${systemd_unitdir}/system
install -m 0644 ${WORKDIR}/rpi-robot-luncher.service ${D}${systemd_unitdir}/system
install -d ${D}${base_sbindir}
install -m 0755 ${WORKDIR}/rpi_robot_init.sh ${D}${base_sbindir}
else
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/rpi_robot_init.sh ${D}${sysconfdir}/init.d/
fi
}
INITSCRIPT_NAME = "rpi_robot_init.sh"
FILES:${PN} = " \
${systemd_unitdir}/system/rpi-robot-luncher.service \
${base_sbindir}/rpi_robot_init.sh \
${sysconfdir}/init.d/rpi_robot_init.sh \
"
- 将rpi-robot-init包添加到我们的上一节创建的packagegroup-rpi-robot.bb里面:
这样就完成了我们systemd自启动luncher的功能了,是不是很简单呢,完整代码见:meta-rpi-robot