问题
As many other person, I want to have a Qt application that run directly when the BeagleBone Black boot. Using the answers from other topics like these: Beaglebone Boot to Qt App ; Start QT Application on bootup on an Embedded Linux Device (Beaglebone Black)
I have a BeagleBone Black revC with Angstrom 2012-09-12.
I achieved to get my application to start on boot with the following service setup:
"autoShow.service"
[Unit]
Description=Autorun Qt app
ConditionFileIsExecutable=/home/root/ShowcaseNice
[Service]
Type=simple
TimeoutStartSec=120
WorkingDirectory=/home/root
ExecStart=/bin/sh -c 'source /etc/profile ; /home/root/ShowcaseNice -qws'
Restart=always
[Install]
WantedBy=multi-user.target
But my application uses a touch interface via a touch screen (4DCAPE-43T) and it doesn't work at all. It seems the tslib library isn't loaded when the systemd run my application. I deduced that because when I add this line to the service [Unit]:
ConditionPathExists=/dev/input/touchscreen0
Then the service doesn't load the application and shows an error message because the path doesn't exist.
Also, if I replace the type from simple to idle, so it load the application only when the BeagleBone is in idle mode and therefore most of the time at the end of every boot processes, it works sometimes.
So I tried to find a way to assure the execution of my application after tslib finished to load, but I couldn't find what is loading tslib (not a service?). So, how can I make sure the file "/dev/input/touchscreen0" is already existing before running?
Thanks!
PS: as my profile file is mentioned in my service because of the definitions of environment variables, here it is:
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
PATH="/usr/local/bin:/usr/bin:/bin"
EDITOR="/bin/vi" # needed for packages like cron
test -z "$TERM" && TERM="vt100" # Basic terminal capab. For screen etc.
if [ ! -e /etc/localtime ]; then
TZ="UTC" # Time Zone. Look at http://theory.uwinnipeg.ca/gnu/glibc/libc_303.html
# for an explanation of how to set this to your local timezone.
export TZ
fi
if [ "$HOME" = "/home/root" ]; then
PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin
fi
if [ "$PS1" ]; then
# works for bash and ash (no other shells known to be in use here)
PS1='\u@\h:\w\$ '
fi
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/* ; do
. $i
done
unset i
fi
PATH=$PATH:/opt/qt/lib
QWS_MOUSE_PROTO="LinuxInput:/dev/input/touchscreen0 MouseMan:/dev/input/mouse2"
SLOTS=/sys/devices/bone_capemgr.8/slots
PINS=/sys/kernel/debug/pinctrl/44e10800.pinmux/pins
export PATH PS1 OPIEDIR QPEDIR QTDIR EDITOR TERM QWS_MOUSE_PROTO SLOTS PINS
echo DM-GPIO-Test > $SLOTS
umask 022
EDIT1: Service file modified to:
"autoShow.service"
[Unit]
Description=Autorun Qt app
ConditionFileIsExecutable=/home/root/ShowcaseNice
After=systemd-modules-load.service
[Service]
Type=oneshot
WorkingDirectory=/home/root
ExecStart=/bin/sh -c 'source /etc/profile ; /home/root/ShowcaseNice -qws'
Restart=always
RemainAfterExit=1;
[Install]
WantedBy=multi-user.target
And I get the followings output after checking the status while the application is running (without touch capabilities working):
root@beaglebone:~# systemctl status systemd-modules-load.service
systemd-modules-load.service - Load Kernel Modules
Loaded: loaded (/lib/systemd/system/systemd-modules-load.service; static)
Active: active (exited) since Sat 2000-01-01 01:16:39 CET; 29s ago
Docs: man:systemd-modules-load.service(8)
man:modules-load.d(5)
Process: 89 ExecStart=/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
CGroup: name=systemd:/system/systemd-modules-load.service
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
root@beaglebone:~# systemctl status autoShow.service
autoShow.service - Autorun Qt app
Loaded: loaded (/lib/systemd/system/autoShow.service; enabled)
Active: activating (start) since Sat 2000-01-01 01:16:39 CET; 32s ago
Main PID: 140 (sh)
CGroup: name=systemd:/system/autoShow.service
|-140 /bin/sh -c source /etc/profile ; /home/root/ShowcaseNice -qws
`-195 /home/root/ShowcaseNice -qws
Jan 01 01:16:39 beaglebone systemd[1]: Starting Autorun Qt app...
Jan 01 01:16:45 beaglebone sh[140]: Cannot open mouse input device '/dev/input/touchscreen0': No such file or directory
root@beaglebone:~# systemctl status rc-local.service
rc-local.service
Loaded: error (Reason: No such file or directory)
Active: inactive (dead)
EDIT2: After doing several test combining the proposition, I found an intermediate solution that seems to work most of the time. But sometimes the touch capabilities still doesn't work. As I am having other troubles with systemd (see this post), I put that on the side.
Here is my almost working service file:
"autoShow.service"
[Unit]
Description=Autorun Qt app
ConditionFileIsExecutable=/home/root/ShowcaseNice
[Service]
After=getty@.service or getty.target
Requires=systemd-modules-load.service
WorkingDirectory=/home/root
ExecStart=/bin/sh -c 'source /etc/profile ; /home/root/ShowcaseNice -qws'
Restart=always
sysVStartPriority=99
Type=idle
[Install]
WantedBy=multi-user.target
回答1:
Nothing actually loads tslib. That's a user land library. If the device doesn't exist when systemd tries to start your program, that is most likely because the kernel module for the hardware hasn't been loaded yet.
After=systemd-modules-load.service
Adding this to your service should make systemd start your program after all of the statically defined kernel modules have loaded.
If that isn't late enough, consider just launching your program from /etc/rc.local or setting your "After=rc-local.service" (execs /etc/rc.local). /etc/rc.local should be the last thing started by systemd by default.
rc-local.service:
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
[Unit]
Description=Local customization
[Service]
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99
rc.local needs to be executable:
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
I hadn't even thought of this, but you can just add SysVStartPriority=[1-99] to your service. It's not a recommended attribute (systemd.service recommends after or before), but it's easier than figuring out where things are in the boot process in systemd. They really need better tools for showing the boot order.
来源:https://stackoverflow.com/questions/25915430/beaglebone-boot-to-qt-app-with-touch-screen