Sample Header Ad - 728x90

Wait for file to be able to be opened with systemd

0 votes
2 answers
86 views
I am trying to use systemd to spin up a ROS2 system on startup that needs to talk to a microcontroller. I have udev rules to create named links to the serial device based on serial number, device id, etc. A path unit configuration waits for the path to exist, and then starts the service, which also waits for the .device file for the path to exist before starting. This works fine, but when the launch file is called and ROS2 attempts to open the connection it always gets a "Device or resource busy" error. I tried implementing a retry system for this, but this approach doesn't work well with how we currently have the serial implementation written, so I wanted to ask if anyone had ideas about another solution? Here is the .service file:
[Unit]
Description=Start PRIMROSE ROS2 Stack
After=dev-MCIU0.device
Requires=dev-MCIU0.device

[Service]
User=pstdl
Group=pstdl
ExecStart=/bin/bash -c '/home/pstdl/Primrose-onboard/src/control/bringup/config/Primrose-startup.sh'
Restart=on-failure
RestartSec=2s

[Install]
WantedBy=multi-user.target
And here is the .path file:
[Unit]
Description= Watch /dev for MCIU0 to appear and then start the PRIMROSE ROS2 stack
After=network-online.target

[Path]
PathExists=/dev/MCIU0

[Install]
WantedBy=multi-user.target
UPDATE: Removing Modem Manager allows the port to be opened, but the port constantly reports no data when attempting to read. Having Modem Manager installed and running the software (not started as a service) allows it to run fine. Some more information about the system: - Jetson Orin NX running JetPack 6 - Communicating with a Teensy 4.1 over USB Serial, comes up as a /dev/ttyACM port. Udev creates a symlink to the /dev/MCIU0 The udev file to create the devices is placed below:
#SUBSYSTEM=="tty",ENV{ID_PATH}=="platform-3610000.usb-usb-0:2.1:1.0",SYMLINK+="rplidar0"
#SUBSYSTEM=="tty",ENV{ID_PATH}=="platform-3610000.usb-usb-0:2.4:1.0",SYMLINK+="vectornav0"
#SUBSYSTEM=="tty",ENV{ID_PATH}=="platform-3610000.usb-usb-0:2.3:1.0",SYMLINK+="zedfp90"

# backup of the local rules, placing this file in /etc/udev/rules.d/ with the appropriate idVendor and idProducts will bring up
# the teensies/sensors with the defined symlink names

KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="00", ENV{channel}="0"
KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="02", ENV{channel}="1"

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="vectornav0"
ACTION=="add", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="rplidar0"
ACTION=="add", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a9", SYMLINK+="zedf9p0"


ENV{channel}=="0" ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="048b", SYMLINK+="MCIU0"
ENV{channel}=="1" ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="048b", SYMLINK+="MCIU1"
Asked by ajgoddu (3 rep)
Jun 23, 2025, 07:16 PM
Last activity: Jun 30, 2025, 07:30 PM