嵌入式Linux应用程序启动脚本在命令行中运行得更好

时间:2017-09-21 14:34:56

标签: embedded-linux systemd

我在Altera FPGA上运行嵌入式Linux。它使用SystemD来运行启动,我在" multi-user.target.wants"中有一个脚本。运行我的应用程序的部分。

当它从启动运行时,我的代码运行速度比从ssh shell运行相同脚本时慢。

我已检查路径是否相同,脚本上的权限是否正确,脚本中是否使用了完整路径。使用' top'我可以看到启动的各种线程的优先级设置相同,但两种启动方式之间的性能完全不同。

完整的脚本是:

#!/bin/sh
sleep 5s
mount /dev/mmcblk0p5 /home/root/linux
cd /home/root/linux/mem_driver
./memdev_load
cd /home/root/linux/gpio_driver
insmod ./gpiodev.ko
mknod /dev/gpiodev c 249 0
sleep 5s
cd /home/root/src/control
mysqld_safe &
up=0
while [ $up -ne 2 ] 
do
    up=$(pgrep mysql | wc -l);
    echo $up
done
sleep 3s
cd /home/root/studio_web/myapp
npm start &
sleep 1s
cd /home/root/src/control
#sleep 1s
./control > /home/root/linux/output.log

已插入各种睡眠命令以尝试确保以正确的顺序启动。

在诊断为什么这种行为方式不同的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

这是您使用的唯一shell脚本吗?或者你有一个执行该单个shell脚本的systemd服务文件?

在这里使用sleep无效。您应该将它们分成单独的shell脚本,然后使用systemd确保shell脚本按顺序运行。

例如,我们首先要挂载目录,因为如果失败,那么以下任何内容都不会成功。所以我们创建了一个systemd挂载服务:

# home-root-linux.mount
[Unit] 
Description=Mount /home/root/linux
Before=gpiodev.service

[Mount]
What=/dev/mmcblk0p5 
Where=/home/root/linux 
Options=defaults

[Install] 
WantedBy=multi-user.target

然后我们可以在执行shell脚本的三个部分之前创建另一个依赖于上面的mount的服务,这三个部分之前由sleep分隔,以确保它们按顺序运行。

# gpiodev.service
[Unit]
Description=Handle gpiodev kernel module
After=home-root-linux.mount
Before=mysqlsafe.service

[Service]
Type=oneshot
ExecStartPre=/home/root/linux/mem_driver/memdev_load
ExecStart=/sbin/insmod gpiodev.ko; /bin/mknod /dev/gpiodev c 249 0
WorkingDirectory=/home/root/linux/gpio_driver
RemainAfterExit=yes
StandardOutput=journal

[Install]
WantedBy=multi-user.target

systemd服务的第二部分(在sleep之后)。我们有一个单独的shellcript,在此示例中放置在/sbin/中,因为它包含while循环,因此最好将其分开:

# mysqlsafe.service
[Unit]
Description=MySQL safe
After=gpiodev.service
Before=npmoutput.service

[Service]
Type=oneshot
ExecStart=/sbin/mysqlsafe.sh
WorkingDirectory=/home/root/src/control
RemainAfterExit=yes
StandardOutput=journal

[Install]
WantedBy=multi-user.target

在上面的systemd服务中执行的shell脚本的第二部分(由于复杂性而分离为单独的文件):

# /sbin/mysqlsafe.sh
#!/bin/sh
mysqld_safe &
up=0
while [ $up -ne 2 ] 
do
    up=$(pgrep mysql | wc -l);
    echo $up
done

systemd服务的第三部分(原始shell脚本的第三部分,由sleep分隔):

# mpmoutput.service
[Unit]
Description=npm and output to log
After=mysqlsafe.service

[Service]
Type=oneshot
ExecStartPre=/usr/bin/npm &
ExecStart=/home/root/src/control > /home/root/linux/output.log
WorkingDirectory=/home/root/studio_web/myapp
RemainAfterExit=yes
StandardOutput=journal

[Install]
WantedBy=multi-user.target

这种方法背后的想法是systemd认识到每个服务的重要性以及对以下服务的依赖,即如果一个服务失败,则队列中的以下服务将不会执行。然后,您可以使用systemctl进行检查,并查看登录journalctl

快速复制,粘贴和编辑。可能包含未经测试或检查的错误。

此处可以找到有关systemd服务文件的更多阅读:https://www.freedesktop.org/software/systemd/man/systemd.service.html