service-systemd.sh
The mandatory step to embedded product: any Python script becomes a supervised service, restarted when it dies and relaunched at boot. The here-document writes the systemd unit in one command, status and journalctl included.
Hardware
An Arduino Portenta X8 (ST STM32MP1 module: quad Cortex-A7 Linux + dual Cortex-M4 real-time core, 8 GB eMMC, 2 GB LPDDR4, on-board Wi-Fi/BT, optional LTE). None; a Python script or binary to supervise.
Wiring
Nothing to wire. Service reachable over SSH on the board.
How it works
tee writes the unit (Restart=always, WantedBy multi-user), daemon-reload registers it, enable --now activates it at once. journalctl centralizes logs.
Running it
Linux side: SSH access (routed USB-C or network) on the Portenta Linux image, bash/Python scripts. Real-time side: Arduino IDE with the « Arduino Mbed OS Portenta X8 Boards » core, application M7 core, flashing via mboot from Linux.
Variants
Add WatchdogSec + sd_notify for a systemd watchdog, or depend on network-online for a cloud service.
service-systemd.sh
#!/bin/bash
# Installe un service systemd pour un script applicatif quelconque.
# Usage : ./service-systemd.sh /root/mon-app.py mon-app
set -e
APP="${1:?Usage: $0 /chemin/app nom-service}"
NOM="${2:?nom du service requis}"
sudo tee /etc/systemd/system/$NOM.service >/dev/null <<UNIT
[Unit]
Description=$NOM (Portenta X8)
After=network-online.target
[Service]
ExecStart=/usr/bin/python3 $APP
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
UNIT
sudo systemctl daemon-reload
sudo systemctl enable --now $NOM
sudo systemctl status $NOM --no-pager | head -8
echo "Logs : journalctl -u $NOM -f"