Inappropriate ioctl on SPI when using launch, works using run
Short version:
Calling the SPI transfer IOCTL works as intended if I run my code from ros2 run ...
, but sets errno
Inappropriate ioctl for device
if I run the same node via ros2 launch ...
.
Longer version:
I have a Raspberry Pi 4, running RaspiOS 64 (Debian Buster), that's connected via SPI to a device I'm trying to communicate with.
I'm using the spidev userspace API and so for the transfers I'm calling the ioctl(fd, SPI_IOC_MESSAGE(dataSize), data)
.
The code has several layers, but finally is wrapped into a rclcpp::Node
and the first transfer is made right in the node's constructor.
The node is then instantiated in an executable consisting of a single-threaded executor running only one instance of this node class (and no other nodes).
My launch file is similarly simple, as it only gets the parameters file and calls the executable (via launch_ros.actions.Node
). The parameters have the same exact values as the default ones declared in the node, and they don't matter for the SPI part of the code (only for a later values conversion etc).
The resulting behaviour is as described in the short version...
Links to the code:
- The launch file Note: for testing I've commented out the fan and the
get_shutdown_on_exit
parts - The node code and the line triggering the error
- The device driver and the call to the
transfer()
function of a SPI wrapper - The SPI wrapper and the
ioctl
that fails
Full log:
$ ros2 launch minirys_ros2 minirys_ve.launch.py
[INFO] [launch]: All log files can be found below /home/minirys/.ros/log/2021-07-24-16-51-28-489220-minirys-10602
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [motors-1]: process started with pid [10605]
[motors-1] [INFO] [1627138288.957487345] [minirys.motors_ve]: Got param: update period (s) 0.01
[motors-1] [INFO] [1627138288.958078059] [minirys.motors_ve]: Got param: stepsPerRevolution 200
[motors-1] [INFO] [1627138288.958214354] [minirys.motors_ve]: Got param: maxSpeed 6.28319
[motors-1] [INFO] [1627138288.958298315] [minirys.motors_ve]: Got param: acceleration 6.28319
[motors-1] [INFO] [1627138288.958402036] [minirys.motors_ve]: SPI: initializing
[motors-1] [INFO] [1627138289.058730929] [minirys.motors_ve]: SPI: initialized
[motors-1] [INFO] [1627138289.058942500] [minirys.motors_ve]: GPIO: initializing
[motors-1] [INFO] [1627138289.059062147] [minirys.motors_ve]: GPIO: initialized
[motors-1] [INFO] [1627138289.059134590] [minirys.motors_ve]: L6470: initializing
[motors-1] [INFO] [1627138289.170296198] [minirys.motors_ve]: L6470: resetting
[motors-1] terminate called after throwing an instance of 'std::runtime_error'
[motors-1] what(): Error transferring via SPI: Inappropriate ioctl for device
[ERROR] [motors-1]: process has died [pid 10605, exit code -6, cmd '/home/minirys/minirys_ws/install/minirys_ros2/lib/minirys_ros2/motors --ros-args -r __ns:=/minirys --params-file /home/minirys/minirys_ws/install/minirys_ros2/share/minirys_ros2/config/params.yaml'].
Hello. currently I wanted to use debian buster ROS2 but I have problem when install it. Do you know how to install it?
@Nur92 this is totally out of scope of the original question, next time just post one of your own, you'll get better answers ;) Anyway, I've built ROS2 from sources using the official documentation: https://docs.ros.org/en/galactic/Inst... skipping the parts with Ubuntu Universe repository and Mint 20 thing, as they're not applicable under Debian.
Also, for anyone coming across this thread: I haven't found the underlying issue - I suspect there's a conflict in accessing registers related to SPI and PWM when the code runs in the same process, so I've just split that into two separate processes. Running them simultaneously but separately works OK.