I’m trying to get a c++ application to load PRU firmware during the boot process using uio.
If I start the service manually (i.e. systemctl start ) it works fine. When I enable the service to load on boot, it fails consistently on the call to prussdrv_open(). I tried setting the systemd unit definition so it would start after specific services (i.e. cloud9), but this didn’t help. I also tried repeating the call to prussdrv_open() in a loop with a 250msec sleep.
Is there a way to configure the systemd unit so that my service won’t start until the uio_pruss driver is ready for use (or some other method)?
I logged the value of geteuid() at the beginning of my application to verify that it was a 0. Is there another type of read/write permission I need to be checking?
If there are any guides to configuring a beagle board (any flavor) to boot to an application that uses the PRU via uio_pruss, please let me know. I wanted to start by setting up the pocketbeagle so that it boots to a simple example application (i.e. EBB chp13 PWM example).
Sorry for the dumb questions! I’m new to linux and there are obviously some key concepts I’m missing.
Is there a way to configure the systemd unit so that my service won’t start until the uio_pruss driver is ready for use (or some other method)?
I use a bash script (called by systemd) that loads the driver (in case of custom settings), wait for the socket nodes and starts the final programm (solar-regler in this case):
`
#!/bin/sh -e
load PRU kernel driver and device tree overlay and
start contoller (Jessie)
uio=/dev/uio5
uncomment to specify ERam size (max. 0x800000, default is 0x40000)
#modprobe uio_pruss extram_pool_sz=0x100000
load device tree overlay
echo solar > /sys/devices/platform/bone_capemgr/slots
wait until kernel driver created the socket nodes
until test -e ${uio}; do sleep 1; done
start controller
/usr/local/bin/solar-regler &
`
The script is named solar-regler.sh and gets invoked by a systemd service, looking like
`
[Unit]
Description=Load solar overlay, start controller (/etc/default/solar-regler.sh)
If there are any guides to configuring a beagle board (any flavor) to boot to an application that uses the PRU via uio_pruss, please let me know. I wanted to start by setting up the pocketbeagle so that it boots to a simple example application (i.e. EBB chp13 PWM example).
In 4.x kernel versions the boot process changed a lot, bad documentation and many bugs. The kernel developers prefer the rpmsg driver, uio_pruss is not well supported. So from my point of view 4.x kernels are still experimental (at least in case of PRU support). For better documentation switch back to the latest 3.8 kernel version.
Thanks very much for sharing the script and advice!
I’ve been tempted to run with a 3.x kernel in the past because it does seem that many of the tutorials, books, etc were based on that. I do like the universal cape approach in the recent builds and it seems easier to work with the uEnv.txt configuration. The rproc approach has a lot of nice features but I think the uio_pruss driver still seems to be a better choice when only a simple interface is needed.
One thing that still confuses me is the fact that I tried putting the call to prussdrv_open() in a loop until it didn’t return an error (250ms delay between attempts). I let it try for hundreds of seconds but it never succeeded. However, if I started the service from a shell (non-root), it worked on the first try. It seems like more of a permissions issue, but I’m not sure what’s missing.
Because of time constraints, I ended up switching to an ESP32 instead of the pocketbeagle for the project I’m working on (the ~2 minute boot time was also a concern). When I get a moment, I’ll try again to figure out how to get my service to wait for the right moment to run and/or have the right permissions.