I haven’t looked at what your wrapper does in detail or what benefits it has over running a readline-enabled version of prudebug in a screen session, but the part for which you seem to be using daemontools is being able to feed commands to a running prudebug instance (which you can totally do with screen too btw!). Obviously the best way to handle that would be to modify prudebug itself to accept connections from a socket, handle commands from any of them, and print the reply to the same socket from which the command was received. This wouldn’t be difficult I think, but let’s instead look at how to do your pipe-trick with systemd.
Creating and managing the service
First there’s the question of whether we want a system service or a user service. In this case, assuming you’re using UIO (and not /dev/mem, ew) everything can run as the debian user so we’ll go with a user service.
Create the directory ~/.config/systemd/user
if it doesn’t already exist and in it create the following two files:
prudebug.socket:
[Unit]
Description=PRU debugger control fifo
[Socket]
# %t = runtime directory (/run for system services, $XDG_RUNTIME_DIR for user services)
ListenFIFO=%t/prudebug/fifo
RemoveOnStop=yes
prudebug.service:
[Unit]
Description=PRU debugger
# make sure the fifo is created first
Requires=prudebug.socket
After=prudebug.socket
[Service]
ExecStart=/usr/local/bin/prudebug
StandardInput=socket
StandardOutput=journal
Tell your systemd user instance to reload its config with
systemctl --user daemon-reload
and then start your service with
systemctl --user start prudebug
or alternatively you can just start the socket unit with
systemctl --user start prudebug.socket
which will create the fifo:
@beaglebone:~$ ls -l $XDG_RUNTIME_DIR/prudebug/fifo
prw-r--r-- 1 debian debian 0 Jul 15 18:40 /run/user/1000/prudebug/fifo|
and then systemd will automatically start the prudebug service when anything is written to the fifo.
Note that stopping the prudebug service will not stop the socket unit, hence the service will be started again if anything is written to the fifo, which systemd will warn you about:
@beaglebone:~$ systemctl --user stop prudebug
Warning: Stopping prudebug.service, but it can still be activated by:
prudebug.socket
If this is undesirable use
systemd --user stop prudebug.socket
instead (which will also stop the prudebug service because of its Requires dependency), or add
PartOf=prudebug.service
to the [Unit]
section of prudebug.socket to automatically propagate stop/restart commands from prudebug to prudebug.socket (though systemctl will erroneously still give the warning, unfortunately).
Beware that by default when the last session of a user logs out, the user’s systemd instance is terminated hence so are the user services managed by it. If you don’t want that, enable “linger” mode for the user:
sudo loginctl enable-linger debian
Note that this will also cause the user’s systemd instance to be started at boot rather than at first login.
Auto-starting services
If you want the socket unit to automatically start when the user’s systemd instance is launched, add
[Install]
WantedBy=sockets.target
to prudebug.socket and then enable the unit with
systemctl --user enable prudebug.socket
If you want the prudebug service to auto-start use
[Install]
WantedBy=default.target
and systemctl --user enable prudebug
Beware however that if you’ve enabled linger-mode for the user as described above then this would cause these units to be started at boot just like system services, which is fine for the socket but with prudebug there might be a risk that it’s started too early, before the uio device is accessible.
I get the impression want to start prudebug on request rather than at boot so I won’t go into details on how to fix this problem, but if you want those details just ask.
Service output
In this example I’ve configured the StandardOutput of prudebug.service to go to journal, which you can monitor with journalctl, e.g.
journalctl --user-unit prudebug
or if you just want to capture the raw output in real-time, without any history:
journalctl -t prudebug -o cat -n0 -f
Alternatively you could ask systemd to send the output to file, e.g.:
StandardOutput=append:%t/prudebug/output
but beware that this never rotates, except at reboot since the location chosen here is in a tmpfs.
Using truncate:
instead of append:
would be better, to get a fresh output log each time prudebug is started, but unfortunately the systemd version in debian buster (v241) and bullseye (v247) are too old to support it, you’d need the one from bullseye-backports (v250) at a minimum. There’s an easy workaround however, just add
ExecStartPre=/bin/rm -f %t/prudebug/output
to the [Service]
section.
Beware also that if rsyslogd is installed (which is the case on the IoT debian images) then it will log some (most? all?) stuff from journal to one or more files in /var/log/ based on how it’s configured. I personally always remove rsyslog to avoid unnecessary eMMC writes and because it is redundant.
Journal itself can be either persistent or kept in ram depending on whether /var/log/journal/
exists or not, but on the beagleboard images this directory doesn’t exist by default hence journal is just kept in ram. Configurable size limits are imposed in either case.
The netcat thing
It’s a complete mystery to me why you’re also using TCP sockets instead of just writing to the fifo directly from the perl script. Recreating this socket that forwards data to the fifo is something that can also be done fairly easily with systemd (and without need for netcat), but I’d like to know what its purpose is before putting any effort into that.
(Also, why on earth are you spawning netcat from the perl script instead of just using IO::Socket::INET to create a TCP socket?)