Beaglebone Black PRU to ARM High Speed Data Transfer

I’m working on a project where the BBB is connected to muitiple peripherals. In particular, the PRU’s will be gathering the majority of data and must send it off to the ARM host. I have set up rpmsg for communicating small messages / control messages between the PRUs and host, but rpmsg is not suitable for transferring data at high speeds. Furthermore, the ARM will be running an ML algorithm continuously and thus needs as much CPU time as possible.

My question: I am unable to figure out how to get the PRUs to directly write to the DDR3 memory. I am running kernel version 5.10.168-ti-rt-r72. I have found multiple posts on here discussing DMA, but none seemed to help me get closer to an answer. Most answers I have stumbled upon rely on the unsupported libpruio / prussdrv libraries or the answers are from many years ago.

Ideally what I would achieve is allocate some memory on the host for the PRUs to write into.
A working example (Host + PRU code) for achieving something along those lines would be truly appreciated. Other tips or reading material (I’ve already read the PRU cookbook and TI AM335X TRM among others) would be very much appreciated.

Take a look at: GitHub - mvduin/py-uio: Userspace I/O in Python and this example https://github.com/mvduin/py-uio/blob/master/pru-examples/ddr-ping.py

Regards,

Thank you for your reply, I did indeed stumble upon this repository before and attempted to get it to work, but it uses the UIO framework right? I cannot get UIO to work on my board with my current kernel version 5.10.168-ti-rt-r72. And, I could be wrong, but I remember reading that UIO and Remoteproc are mutually exclusive as described here.

After following the installation instructions in the repository you linked, remoteproc is indeed deactivated and the kernel drivers are loaded:

>> lsmod | grep uio
uio_pruss              16384  0
uio_pdrv_genirq        16384  0
uio                    20480  2 uio_pruss,uio_pdrv_genirq

but no uio devices are present, and running the basic_test.py results in
FileNotFoundError: [Errno 2] No such file or directory: '/dev/uio/pruss/module' :

>>> ls /dev/u*
/dev/ubi_ctrl  /dev/uhid  /dev/uinput  /dev/urandom
1 Like

After checking the logs after boot, the error messages were as follows:

[    0.250321] platform 4a300000.pruss: Cannot lookup hwmod 'pruss'
[   11.128146] sysfs: cannot create duplicate filename '/bus/platform/devices/4a300000.pruss'
[   63.517534] pruss_uio 4a300000.pruss: _od_fail_runtime_resume: FIXME: missing hwmod/omap_dev info
[   63.517569] pruss_uio 4a300000.pruss: pm_runtime_get_sync() failed

what does sudo beagle-version show? as long as you only load the AM335X-PRU-UIO-00A0.dtbo overlay it works…

Regards,

The output of sudo beagle-version is:

eeprom:[A335BNLT00C02247SBB11369]
model:[TI_AM335x_BeagleBone_Black]
dogtag:[BeagleBoard.org Debian Bullseye IoT Image 2023-09-02]
bootloader:[microSD-(push-button)]:[/dev/mmcblk0]:[U-Boot SPL 2022.04-ge0d31da5 (Aug 04 2023 - 18:48:26 +0000)]:[location: dd MBR]
bootloader:[eMMC-(default)]:[/dev/mmcblk1]:[U-Boot SPL 2022.04-ge0d31da5 (Aug 04 2023 - 18:48:26 +0000)]:[location: dd MBR]
UBOOT: Booted Device-Tree:[am335x-boneblack-uboot-univ.dts]
UBOOT: Loaded Overlay:[AM335X-PRU-UIO-00A0]
UBOOT: Loaded Overlay:[BB-BONE-eMMC1-01-00A0.kernel]
kernel:[5.10.168-ti-rt-r72]
nodejs:[v12.22.12]
/boot/uEnv.txt Settings:
uboot_overlay_options:[enable_uboot_overlays=1]
uboot_overlay_options:[disable_uboot_overlay_video=1]
uboot_overlay_options:[disable_uboot_overlay_audio=1]
uboot_overlay_options:[disable_uboot_overlay_wireless=1]
uboot_overlay_options:[disable_uboot_overlay_adc=1]
uboot_overlay_options:[uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo]
uboot_overlay_options:[enable_uboot_cape_universal=1]
pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]
pkg:[bb-cape-overlays]:[4.14.20210821.0-0~bullseye+20210821]
pkg:[bb-customizations]:[1.20231007.0-0~bullseye+20231007]
pkg:[bb-usb-gadgets]:[1.20231003.1-0~bullseye+20231003]
pkg:[bb-wl18xx-firmware]:[1.20230414.0-0~bullseye+20230414]
pkg:[kmod]:[28-1]
WARNING:pkg:[librobotcontrol]:[NOT_INSTALLED]
pkg:[firmware-ti-connectivity]:[20210315-3]
groups:[debian : debian adm kmem dialout cdrom floppy sudo audio dip video plugdev users systemd-journal input render bluetooth netdev i2c gpio admin tisdk weston-launch cloud9ide spi]
cmdline:[console=ttyS0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk1p1 ro rootfstype=ext4 rootwait]
dmesg | grep remote
[   10.847468] remoteproc remoteproc0: wkup_m3 is available
[   44.144353] remoteproc remoteproc0: powering up wkup_m3
[   44.144391] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 217148
[   44.144685] remoteproc remoteproc0: remote processor wkup_m3 is now up
dmesg | grep pru
[    0.250321] platform 4a300000.pruss: Cannot lookup hwmod 'pruss'
[   11.128146] sysfs: cannot create duplicate filename '/bus/platform/devices/4a300000.pruss'
[   63.517534] pruss_uio 4a300000.pruss: _od_fail_runtime_resume: FIXME: missing hwmod/omap_dev info
[   63.517569] pruss_uio 4a300000.pruss: pm_runtime_get_sync() failed
dmesg | grep pinctrl-single
[   10.307437] pinctrl-single 44e10800.pinmux: 142 pins, size 568
dmesg | grep gpio-of-helper
[   10.309141] gpio-of-helper ocp:cape-universal: Failed to get gpio property of 'P8_03'
[   10.309160] gpio-of-helper ocp:cape-universal: Failed to create gpio entry
[   11.132123] gpio-of-helper ocp:cape-universal: Allocated GPIO id=0 name='P8_03'
[   11.132394] gpio-of-helper ocp:cape-universal: Allocated GPIO id=1 name='P8_04'
[   11.132592] gpio-of-helper ocp:cape-universal: Allocated GPIO id=2 name='P8_05'
[   11.132799] gpio-of-helper ocp:cape-universal: Allocated GPIO id=3 name='P8_06'
[   11.133394] gpio-of-helper ocp:cape-universal: Allocated GPIO id=4 name='P8_07'
[   11.133600] gpio-of-helper ocp:cape-universal: Allocated GPIO id=5 name='P8_08'
[   11.133838] gpio-of-helper ocp:cape-universal: Allocated GPIO id=6 name='P8_09'
[   11.134050] gpio-of-helper ocp:cape-universal: Allocated GPIO id=7 name='P8_10'
[   11.134262] gpio-of-helper ocp:cape-universal: Allocated GPIO id=8 name='P8_11'
[   11.134460] gpio-of-helper ocp:cape-universal: Allocated GPIO id=9 name='P8_12'
[   11.134718] gpio-of-helper ocp:cape-universal: Allocated GPIO id=10 name='P8_13'
[   11.134924] gpio-of-helper ocp:cape-universal: Allocated GPIO id=11 name='P8_14'
[   11.135128] gpio-of-helper ocp:cape-universal: Allocated GPIO id=12 name='P8_15'
[   11.135329] gpio-of-helper ocp:cape-universal: Allocated GPIO id=13 name='P8_16'
[   11.142565] gpio-of-helper ocp:cape-universal: Allocated GPIO id=14 name='P8_17'
[   11.142794] gpio-of-helper ocp:cape-universal: Allocated GPIO id=15 name='P8_18'
[   11.143038] gpio-of-helper ocp:cape-universal: Allocated GPIO id=16 name='P8_19'
[   11.143243] gpio-of-helper ocp:cape-universal: Allocated GPIO id=17 name='P8_20'
[   11.143446] gpio-of-helper ocp:cape-universal: Allocated GPIO id=18 name='P8_21'
[   11.143720] gpio-of-helper ocp:cape-universal: Allocated GPIO id=19 name='P8_22'
[   11.143941] gpio-of-helper ocp:cape-universal: Allocated GPIO id=20 name='P8_23'
[   11.144147] gpio-of-helper ocp:cape-universal: Allocated GPIO id=21 name='P8_24'
[   11.144358] gpio-of-helper ocp:cape-universal: Allocated GPIO id=22 name='P8_25'
[   11.144544] gpio-of-helper ocp:cape-universal: Allocated GPIO id=23 name='P8_26'
[   11.144748] gpio-of-helper ocp:cape-universal: Allocated GPIO id=24 name='P8_27'
[   11.144946] gpio-of-helper ocp:cape-universal: Allocated GPIO id=25 name='P8_28'
[   11.145155] gpio-of-helper ocp:cape-universal: Allocated GPIO id=26 name='P8_29'
[   11.145360] gpio-of-helper ocp:cape-universal: Allocated GPIO id=27 name='P8_30'
[   11.145568] gpio-of-helper ocp:cape-universal: Allocated GPIO id=28 name='P8_31'
[   11.145768] gpio-of-helper ocp:cape-universal: Allocated GPIO id=29 name='P8_32'
[   11.145963] gpio-of-helper ocp:cape-universal: Allocated GPIO id=30 name='P8_33'
[   11.146167] gpio-of-helper ocp:cape-universal: Allocated GPIO id=31 name='P8_34'
[   11.146371] gpio-of-helper ocp:cape-universal: Allocated GPIO id=32 name='P8_35'
[   11.146559] gpio-of-helper ocp:cape-universal: Allocated GPIO id=33 name='P8_36'
[   11.146772] gpio-of-helper ocp:cape-universal: Allocated GPIO id=34 name='P8_37'
[   11.146951] gpio-of-helper ocp:cape-universal: Allocated GPIO id=35 name='P8_38'
[   11.147164] gpio-of-helper ocp:cape-universal: Allocated GPIO id=36 name='P8_39'
[   11.147363] gpio-of-helper ocp:cape-universal: Allocated GPIO id=37 name='P8_40'
[   11.160445] gpio-of-helper ocp:cape-universal: Allocated GPIO id=38 name='P8_41'
[   11.160686] gpio-of-helper ocp:cape-universal: Allocated GPIO id=39 name='P8_42'
[   11.160875] gpio-of-helper ocp:cape-universal: Allocated GPIO id=40 name='P8_43'
[   11.161075] gpio-of-helper ocp:cape-universal: Allocated GPIO id=41 name='P8_44'
[   11.161284] gpio-of-helper ocp:cape-universal: Allocated GPIO id=42 name='P8_45'
[   11.161474] gpio-of-helper ocp:cape-universal: Allocated GPIO id=43 name='P8_46'
[   11.161716] gpio-of-helper ocp:cape-universal: Allocated GPIO id=44 name='P9_11'
[   11.161924] gpio-of-helper ocp:cape-universal: Allocated GPIO id=45 name='P9_12'
[   11.162124] gpio-of-helper ocp:cape-universal: Allocated GPIO id=46 name='P9_13'
[   11.162326] gpio-of-helper ocp:cape-universal: Allocated GPIO id=47 name='P9_14'
[   11.162509] gpio-of-helper ocp:cape-universal: Allocated GPIO id=48 name='P9_15'
[   11.162740] gpio-of-helper ocp:cape-universal: Allocated GPIO id=49 name='P9_16'
[   11.162940] gpio-of-helper ocp:cape-universal: Allocated GPIO id=50 name='P9_17'
[   11.163128] gpio-of-helper ocp:cape-universal: Allocated GPIO id=51 name='P9_18'
[   11.163338] gpio-of-helper ocp:cape-universal: Allocated GPIO id=52 name='P9_19'
[   11.163725] gpio-of-helper ocp:cape-universal: Allocated GPIO id=53 name='P9_20'
[   11.163988] gpio-of-helper ocp:cape-universal: Allocated GPIO id=54 name='P9_21'
[   11.164196] gpio-of-helper ocp:cape-universal: Allocated GPIO id=55 name='P9_22'
[   11.164387] gpio-of-helper ocp:cape-universal: Allocated GPIO id=56 name='P9_23'
[   11.164591] gpio-of-helper ocp:cape-universal: Allocated GPIO id=57 name='P9_24'
[   11.165082] gpio-of-helper ocp:cape-universal: Allocated GPIO id=58 name='P9_25'
[   11.165331] gpio-of-helper ocp:cape-universal: Allocated GPIO id=59 name='P9_26'
[   11.165564] gpio-of-helper ocp:cape-universal: Allocated GPIO id=60 name='P9_27'
[   11.165753] gpio-of-helper ocp:cape-universal: Allocated GPIO id=61 name='P9_28'
[   11.166001] gpio-of-helper ocp:cape-universal: Allocated GPIO id=62 name='P9_29'
[   11.166189] gpio-of-helper ocp:cape-universal: Allocated GPIO id=63 name='P9_30'
[   11.166395] gpio-of-helper ocp:cape-universal: Allocated GPIO id=64 name='P9_31'
[   11.166602] gpio-of-helper ocp:cape-universal: Allocated GPIO id=65 name='P9_41'
[   11.166790] gpio-of-helper ocp:cape-universal: Allocated GPIO id=66 name='P9_91'
[   11.166997] gpio-of-helper ocp:cape-universal: Allocated GPIO id=67 name='P9_42'
[   11.167211] gpio-of-helper ocp:cape-universal: Allocated GPIO id=68 name='P9_92'
[   11.167222] gpio-of-helper ocp:cape-universal: ready
dmesg | grep wlcore
lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
END

So you’ve loaded the older “generic” /lib/firmware/AM335X-PRU-UIO-00A0.dtbo… [AM335X-PRU-UIO-00A0] you need the kernel specific one…

So open, /boot/uEnv.txt and change:

uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo -> uboot_overlay_pru=AM335X-PRU-UIO-00A0.dtbo

on your next reboot, run again and this should change:

UBOOT: Loaded Overlay:[AM335X-PRU-UIO-00A0]
UBOOT: Loaded Overlay:[AM335X-PRU-UIO-00A0.kernel]

Regards,

After making this change and rebooting, the board does not boot at all, and the blue LEDs keep flickering.

U-Boot SPL 2022.04-ge0d31da5 (Aug 04 2023 - 18:48:26 +0000)
Trying to boot from MMC1


U-Boot 2022.04-ge0d31da5 (Aug 04 2023 - 18:48:26 +0000)

CPU  : AM335X-GP rev 2.1
Model: TI AM335x BeagleBone Black
DRAM:  512 MiB
Reset Source: Global external warm reset has occurred.
Reset Source: Global warm SW reset has occurred.
Reset Source: Power-on reset has occurred.
RTC 32KCLK Source: External.
Core:  150 devices, 14 uclasses, devicetree: separate
WDT:   Started wdt@44e35000 with servicing (60s timeout)
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
Loading Environment from EXT4... ** File not found /boot/uboot.env **

** Unable to read "/boot/uboot.env" from mmc0:1 **
Board: BeagleBone Black
<ethaddr> not set. Validating first E-fuse MAC
BeagleBone Black:
BeagleBone Cape EEPROM: no EEPROM at address: 0x54
BeagleBone Cape EEPROM: no EEPROM at address: 0x55
BeagleBone Cape EEPROM: no EEPROM at address: 0x56
BeagleBone Cape EEPROM: no EEPROM at address: 0x57
Net:   eth2: ethernet@4a100000, eth3: usb_ether
Press SPACE to abort autoboot in 0 seconds
board_name=[A335BNLT] ...
board_rev=[000C] ...
switch to partitions #0, OK
mmc0 is current device
SD/MMC found on device 0
Couldn't find partition 0:2 0x82000000
Can't set block device
Couldn't find partition 0:2 0x82000000
Can't set block device
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk mmc@48060000.blk...
Scanning disk mmc@481d8000.blk...
Found 3 disks
No EFI system partition
BootOrder not defined
EFI boot manager: Cannot load any image
gpio: pin 56 (gpio 56) value is 0
gpio: pin 55 (gpio 55) value is 0
gpio: pin 54 (gpio 54) value is 0
gpio: pin 53 (gpio 53) value is 1
switch to partitions #0, OK
mmc0 is current device
gpio: pin 54 (gpio 54) value is 1
Checking for: /uEnv.txt ...
Checking for: /boot/uEnv.txt ...
gpio: pin 55 (gpio 55) value is 1
1750 bytes read in 4 ms (426.8 KiB/s)
Loaded environment from /boot/uEnv.txt
Checking if uname_r is set in /boot/uEnv.txt...
gpio: pin 56 (gpio 56) value is 1
Running uname_boot ...
loading /boot/vmlinuz-5.10.168-ti-rt-r72 ...
11432448 bytes read in 723 ms (15.1 MiB/s)
debug: [enable_uboot_overlays=1] ...
debug: [enable_uboot_cape_universal=1] ...
debug: [uboot_base_dtb_univ=am335x-boneblack-uboot-univ.dtb] ...
uboot_overlays: [uboot_base_dtb=am335x-boneblack-uboot-univ.dtb] ...
uboot_overlays: Switching too: dtb=am335x-boneblack-uboot-univ.dtb ...
loading /boot/dtbs/5.10.168-ti-rt-r72/am335x-boneblack-uboot-univ.dtb ...
210757 bytes read in 19 ms (10.6 MiB/s)
Found 0 extension board(s).
uboot_overlays: [fdt_buffer=0x60000] ...
uboot_overlays: uboot loading of [BB-ADC-00A0.dtbo] disabled by /boot/uEnv.txt [disable_uboot_overlay_adc=1]...
uboot_overlays: loading /boot/dtbs/5.10.168-ti-rt-r72/overlays/BB-BONE-eMMC1-01-00A0.dtbo ...
1605 bytes read in 9 ms (173.8 KiB/s)
uboot_overlays: uboot loading of [BB-HDMI-TDA998x-00A0.dtbo] disabled by /boot/uEnv.txt [disable_uboot_overlay_video=1]...
uboot_overlays: loading /boot/dtbs/5.10.168-ti-rt-r72/overlays/AM335X-PRU-UIO-00A0.dtbo ...
700 bytes read in 10 ms (68.4 KiB/s)
loading /boot/initrd.img-5.10.168-ti-rt-r72 ...
8076796 bytes read in 517 ms (14.9 MiB/s)
debug: [console=ttyS0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100] ...
debug: [bootz 0x82000000 0x88080000:7b3dfc 88000000] ...
Kernel image @ 0x82000000 [ 0x000000 - 0xae7200 ]
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
   Loading Ramdisk to 8f84c000, end 8ffffdfc ... OK
   Loading Device Tree to 8f7b5000, end 8f84bfff ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.10.168-ti-rt-r72 (voodoo@rpi4b4g-09) (gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #1bullseye SMP PREEMPT_RT Sat Sep 30 03:42:46 UTC 2023
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt: Machine model: TI AM335x BeagleBone Black
[    0.000000] Memory policy: Data cache writeback
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 48 MiB at 0x9c800000
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000080000000-0x000000009fdfffff]
[    0.000000]   HighMem  empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080000000-0x000000009fdfffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000009fdfffff]
[    0.000000] CPU: All CPU(s) started in SVC mode.
[    0.000000] AM335X ES2.1 (sgx neon)
[    0.000000] percpu: Embedded 17 pages/cpu s39584 r8192 d21856 u69632
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 129412
[    0.000000] Kernel command line: console=ttyS0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100
debian@BeagleBone:~$ sudo beagle-version
[sudo] password for debian: 
eeprom:[A335BNLT000CyywwBBoxxxx]
model:[TI_AM335x_BeagleBone_Black]
dogtag:[BeagleBoard.org Debian Bullseye IoT Image 2023-09-02]
bootloader:[microSD-(push-button)]:[/dev/mmcblk0]:[U-Boot SPL 2022.04-ge0d31da5 (Aug 04 2023 - 18:48:26 +0000)]:[location: dd MBR]
UBOOT: Booted Device-Tree:[am335x-boneblack-uboot-univ.dts]
UBOOT: Loaded Overlay:[AM335X-PRU-UIO-00A0.kernel]
UBOOT: Loaded Overlay:[BB-BONE-eMMC1-01-00A0.kernel]
kernel:[5.10.168-ti-rt-r72]
nodejs:[v12.22.12]
/boot/uEnv.txt Settings:
uboot_overlay_options:[enable_uboot_overlays=1]
uboot_overlay_options:[disable_uboot_overlay_video=1]
uboot_overlay_options:[disable_uboot_overlay_audio=1]
uboot_overlay_options:[disable_uboot_overlay_wireless=1]
uboot_overlay_options:[disable_uboot_overlay_adc=1]
uboot_overlay_options:[enable_uboot_cape_universal=1]
uboot_overlay_options:[uboot_overlay_pru=AM335X-PRU-UIO-00A0.dtbo]
pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]
pkg:[bb-cape-overlays]:[4.14.20210821.0-0~bullseye+20210821]
pkg:[bb-customizations]:[1.20230720.1-0~bullseye+20230720]
pkg:[bb-usb-gadgets]:[1.20230414.0-0~bullseye+20230414]
pkg:[bb-wl18xx-firmware]:[1.20230414.0-0~bullseye+20230414]
pkg:[kmod]:[28-1]
WARNING:pkg:[librobotcontrol]:[NOT_INSTALLED]
pkg:[firmware-ti-connectivity]:[20210315-3]
groups:[debian : debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal input render bluetooth netdev i2c gpio admin tisdk weston-launch cloud9ide]
cmdline:[console=ttyS0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100]
dmesg | grep remote
[   10.771323] remoteproc remoteproc0: wkup_m3 is available
[   51.988703] remoteproc remoteproc0: powering up wkup_m3
[   51.988744] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 217148
[   51.989018] remoteproc remoteproc0: remote processor wkup_m3 is now up
dmesg | grep pru
dmesg | grep pinctrl-single
[   10.236163] pinctrl-single 44e10800.pinmux: 142 pins, size 568
dmesg | grep gpio-of-helper
[   10.237686] gpio-of-helper ocp:cape-universal: Failed to get gpio property of 'P8_03'
[   10.237703] gpio-of-helper ocp:cape-universal: Failed to create gpio entry
[   11.057563] gpio-of-helper ocp:cape-universal: Allocated GPIO id=0 name='P8_03'
[   11.057836] gpio-of-helper ocp:cape-universal: Allocated GPIO id=1 name='P8_04'
[   11.058055] gpio-of-helper ocp:cape-universal: Allocated GPIO id=2 name='P8_05'
[   11.058238] gpio-of-helper ocp:cape-universal: Allocated GPIO id=3 name='P8_06'
[   11.058789] gpio-of-helper ocp:cape-universal: Allocated GPIO id=4 name='P8_07'
[   11.059032] gpio-of-helper ocp:cape-universal: Allocated GPIO id=5 name='P8_08'
[   11.059253] gpio-of-helper ocp:cape-universal: Allocated GPIO id=6 name='P8_09'
[   11.059487] gpio-of-helper ocp:cape-universal: Allocated GPIO id=7 name='P8_10'
[   11.066727] gpio-of-helper ocp:cape-universal: Allocated GPIO id=8 name='P8_11'
[   11.066952] gpio-of-helper ocp:cape-universal: Allocated GPIO id=9 name='P8_12'
[   11.067231] gpio-of-helper ocp:cape-universal: Allocated GPIO id=10 name='P8_13'
[   11.067436] gpio-of-helper ocp:cape-universal: Allocated GPIO id=11 name='P8_14'
[   11.067715] gpio-of-helper ocp:cape-universal: Allocated GPIO id=12 name='P8_15'
[   11.067936] gpio-of-helper ocp:cape-universal: Allocated GPIO id=13 name='P8_16'
[   11.068173] gpio-of-helper ocp:cape-universal: Allocated GPIO id=14 name='P8_17'
[   11.068381] gpio-of-helper ocp:cape-universal: Allocated GPIO id=15 name='P8_18'
[   11.068571] gpio-of-helper ocp:cape-universal: Allocated GPIO id=16 name='P8_19'
[   11.068772] gpio-of-helper ocp:cape-universal: Allocated GPIO id=17 name='P8_20'
[   11.068967] gpio-of-helper ocp:cape-universal: Allocated GPIO id=18 name='P8_21'
[   11.069165] gpio-of-helper ocp:cape-universal: Allocated GPIO id=19 name='P8_22'
[   11.069395] gpio-of-helper ocp:cape-universal: Allocated GPIO id=20 name='P8_23'
[   11.069596] gpio-of-helper ocp:cape-universal: Allocated GPIO id=21 name='P8_24'
[   11.069806] gpio-of-helper ocp:cape-universal: Allocated GPIO id=22 name='P8_25'
[   11.069990] gpio-of-helper ocp:cape-universal: Allocated GPIO id=23 name='P8_26'
[   11.070192] gpio-of-helper ocp:cape-universal: Allocated GPIO id=24 name='P8_27'
[   11.070389] gpio-of-helper ocp:cape-universal: Allocated GPIO id=25 name='P8_28'
[   11.070573] gpio-of-helper ocp:cape-universal: Allocated GPIO id=26 name='P8_29'
[   11.070766] gpio-of-helper ocp:cape-universal: Allocated GPIO id=27 name='P8_30'
[   11.070951] gpio-of-helper ocp:cape-universal: Allocated GPIO id=28 name='P8_31'
[   11.071192] gpio-of-helper ocp:cape-universal: Allocated GPIO id=29 name='P8_32'
[   11.071404] gpio-of-helper ocp:cape-universal: Allocated GPIO id=30 name='P8_33'
[   11.090690] gpio-of-helper ocp:cape-universal: Allocated GPIO id=31 name='P8_34'
[   11.090928] gpio-of-helper ocp:cape-universal: Allocated GPIO id=32 name='P8_35'
[   11.091119] gpio-of-helper ocp:cape-universal: Allocated GPIO id=33 name='P8_36'
[   11.091319] gpio-of-helper ocp:cape-universal: Allocated GPIO id=34 name='P8_37'
[   11.091513] gpio-of-helper ocp:cape-universal: Allocated GPIO id=35 name='P8_38'
[   11.091872] gpio-of-helper ocp:cape-universal: Allocated GPIO id=36 name='P8_39'
[   11.092137] gpio-of-helper ocp:cape-universal: Allocated GPIO id=37 name='P8_40'
[   11.092377] gpio-of-helper ocp:cape-universal: Allocated GPIO id=38 name='P8_41'
[   11.092580] gpio-of-helper ocp:cape-universal: Allocated GPIO id=39 name='P8_42'
[   11.092786] gpio-of-helper ocp:cape-universal: Allocated GPIO id=40 name='P8_43'
[   11.092970] gpio-of-helper ocp:cape-universal: Allocated GPIO id=41 name='P8_44'
[   11.093170] gpio-of-helper ocp:cape-universal: Allocated GPIO id=42 name='P8_45'
[   11.093368] gpio-of-helper ocp:cape-universal: Allocated GPIO id=43 name='P8_46'
[   11.093557] gpio-of-helper ocp:cape-universal: Allocated GPIO id=44 name='P9_11'
[   11.093778] gpio-of-helper ocp:cape-universal: Allocated GPIO id=45 name='P9_12'
[   11.093977] gpio-of-helper ocp:cape-universal: Allocated GPIO id=46 name='P9_13'
[   11.094221] gpio-of-helper ocp:cape-universal: Allocated GPIO id=47 name='P9_14'
[   11.094427] gpio-of-helper ocp:cape-universal: Allocated GPIO id=48 name='P9_15'
[   11.094609] gpio-of-helper ocp:cape-universal: Allocated GPIO id=49 name='P9_16'
[   11.094820] gpio-of-helper ocp:cape-universal: Allocated GPIO id=50 name='P9_17'
[   11.095003] gpio-of-helper ocp:cape-universal: Allocated GPIO id=51 name='P9_18'
[   11.095201] gpio-of-helper ocp:cape-universal: Allocated GPIO id=52 name='P9_19'
[   11.095417] gpio-of-helper ocp:cape-universal: Allocated GPIO id=53 name='P9_20'
[   11.095731] gpio-of-helper ocp:cape-universal: Allocated GPIO id=54 name='P9_21'
[   11.095956] gpio-of-helper ocp:cape-universal: Allocated GPIO id=55 name='P9_22'
[   11.096180] gpio-of-helper ocp:cape-universal: Allocated GPIO id=56 name='P9_23'
[   11.096389] gpio-of-helper ocp:cape-universal: Allocated GPIO id=57 name='P9_24'
[   11.096899] gpio-of-helper ocp:cape-universal: Allocated GPIO id=58 name='P9_25'
[   11.097108] gpio-of-helper ocp:cape-universal: Allocated GPIO id=59 name='P9_26'
[   11.097321] gpio-of-helper ocp:cape-universal: Allocated GPIO id=60 name='P9_27'
[   11.097552] gpio-of-helper ocp:cape-universal: Allocated GPIO id=61 name='P9_28'
[   11.097755] gpio-of-helper ocp:cape-universal: Allocated GPIO id=62 name='P9_29'
[   11.097968] gpio-of-helper ocp:cape-universal: Allocated GPIO id=63 name='P9_30'
[   11.098176] gpio-of-helper ocp:cape-universal: Allocated GPIO id=64 name='P9_31'
[   11.098396] gpio-of-helper ocp:cape-universal: Allocated GPIO id=65 name='P9_41'
[   11.098594] gpio-of-helper ocp:cape-universal: Allocated GPIO id=66 name='P9_91'
[   11.098778] gpio-of-helper ocp:cape-universal: Allocated GPIO id=67 name='P9_42'
[   11.098977] gpio-of-helper ocp:cape-universal: Allocated GPIO id=68 name='P9_92'
[   11.098988] gpio-of-helper ocp:cape-universal: ready
dmesg | grep wlcore
lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
END
debian@BeagleBone:~$ tree /dev/uio
/dev/uio
└── pruss
    ├── irq2 -> ../../uio0
    ├── irq3 -> ../../uio1
    ├── irq4 -> ../../uio2
    ├── irq5 -> ../../uio3
    ├── irq6 -> ../../uio4
    ├── irq7 -> ../../uio5
    ├── irq8 -> ../../uio6
    ├── irq9 -> ../../uio7
    └── module -> ../../uio0

1 directory, 9 files

The board is not booting so I will retry this tomorrow with a clean 5.10 image and report my results back here, thank you @RobertCNelson for your help thus far!

After the fresh install UIO and PRUSS have loaded and work, I am not sure why previously it would not boot anymore. Thank you very much for your help @RobertCNelson!

As expected however, remoteproc does not work with the PRUs anymore. Is there truly no way to incorporate both such that its possible to use RPMSG for small control messages and UIO for larger data transfers?

For your usage, the main difference between UIO and remoteproc is how you load firmware and start/stop the PRU cores. The ddr-ping application referred to above just allocates a (small) chunk of memory in SDRAM and passes the address to the PRU code. If you want to pass large chunks of data between the PRU and Linux, just carve out a chunk of reserved memory using device tree and use it as needed:

https://www.kernel.org/doc/Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml

…you may need the no-map attribute to avoid cache coherency issues with the ARM cores.

i suggest instead that you have the pru’s write to pru memory (28K total) and have the arm chip read this memory. This sidesteps the need for the pru’s to know where the allocated memory is in linux space.

A ring buffer is the ideal means to do this. An example can be found here: Turnkey PRU deskclock application for BBB … it achieves great speed b/c both processors are active simultaneously, one reading (arm) and the other writing. The stress test video shows a data transfer of ~1.2MB / sec (60MB in 50 seconds).

it is the reverse direction of what you are needing and uses remoteproc. the linux program must run as root to have access to /dev/mem.

good luck
gomer

Yes, a ring buffer is fine!

But instead of using three blocks of 28k PRUSS memory, I recommend using a single continguous block of kernel memory allocated by the uio_pruss driver (ie 256k). The PRU directly writes to that memory (over L3 bus), where the ARM can fetch the data. Find source code in examples rb_file or rb_oszi. (In case of parallel access, ARM reading blocks PRU writing.)

No root access, all is running from user space.

Regards

I have done exactly what you are trying to do on a previous project with the BBAI. The PRU has direct access to physical memory. Writing Linux RAM is just a memcpy in PRU code. I used one PRU core to do high speed read 16mhz on ADC and pushed memory to the second core to write 4k chunks to system RAM. every 256k the PRU would write a rpmsg to the Linux thread blocked on rpmsg read.

I defined a block of shared memory.

#define LINUX_SHARED_RAM_ADDRESS 0x90000000

uint8_t volatile __far * const LINUX_SHARED_RAM = (uint8_t*)LINUX_SHARED_RAM_ADDRESS);

your pru_code()
{
uint32_t index = 0;
memcpy((void*)&LINUX_SHARED_RAM[index], local_data, sizeof(local_data);
index+= sizeof(local_data);
}

I added an 8mb shared memory block to the Linux device tree in the reserved memory section.
sample_memory_region: sample-memory@90000000 {
compatible = “shared-dma-pool”;
reg = <0x0 0x90000000 0x0 0x800000>;
reusable;
status = “okay”;
};
In Linux just map the memory block into user space with mmap
https://man7.org/linux/man-pages/man2/mmap.2.html

You can utilize the RPMessage protocol to notify Linux when a block of memory has been received.

look at the Rpmessage examples to understand ARM ↔ PRU communication

How did you load the overlay exactly? Trying to replicate your solution I came up with the following dts file to reserve 64 mb of memory:

/dts-v1/;
/plugin/;
/* Reserve 64M DDR memory */
/ {

    compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green";

    // identification
    part-number = "AM335X-BBBSENSE-RESERVED-MEMORY";
    version = "00A0";

	fragment@0 {
		target-path = "/";
		__overlay__ {
			reserved-memory {
				#address-cells = <1>;
				#size-cells = <1>;
				ranges;
				bbbsense_reserved: bbbsense_reserved@90000000 {
					reg = <0x90000000 0x06400000>;
					no-map;
					status = "okay";
				};
			};
		};
	};
};

but I don’t fully grasp device tree overlays yet, how do go about loading this? Compiling this dts file the compiler seems to complain:

bbb-reserve-prumem.dts:18.5-12: Warning (ranges_format): /fragment@0/__overlay__/reserved-memory:ranges: empty "ranges" property but its #address-cells (1) differs from /fragment@0/__overlay__ (2)
bbb-reserve-prumem.dts:15.20-24.6: Warning (avoid_default_addr_size): /fragment@0/__overlay__/reserved-memory: Relying on default #address-cells value
bbb-reserve-prumem.dts:15.20-24.6: Warning (avoid_default_addr_size): /fragment@0/__overlay__/reserved-memory: Relying on default #size-cells value
bbb-reserve-prumem.dtbo: Warning (avoid_unnecessary_addr_size): Failed prerequisite 'avoid_default_addr_size'
bbb-reserve-prumem.dtbo: Warning (unique_unit_address): Failed prerequisite 'avoid_default_addr_size'

I didn’t bother with a device tree overlay. Just modify the device tree file directly.
I was using linux version 4.19-ti

on the BeagleBone board from the Linux prompt run these commands to get the device tree code

** Substitute your OS dtb directory **
cd /opt/source/dtb-4.19-ti
git clone GitHub - beagleboard/BeagleBoard-DeviceTrees: mirror of: https://git.beagleboard.org/beagleboard/BeagleBoard-DeviceTrees
sudo apt install device-tree-compiler
sudo apt update
sudo apt upgrade

change to the BeagleBoard-DeviceTrees directory and run ‘make’ then ‘make install’
this installs the device trees on the BBB

i modified the am5729-beagleboneai.dts file directly and added the sample_memory entry I listed in the post.
I think the file you will need to modify is the src/arm/am335x-boneblack-common.dtsi file.
I am not sure on this. You will have to do a bit of digging to be sure. I used a block of memory after the processor carveouts.

look for a memory tag and add your new entry right after and recompile the tree.
make && make install

this is the entry I used


sample_memory_region: sample-memory@90000000 {
    compatible = "shared-dma-pool";
    reg = <0x0 0x90000000 0x0 0x800000>; 0x90000000 is the address in physical memory to use 0x800000 is the length of the block (8mb).
    reusable;
    status = "okay";
};

if the system boots ok, no memory conflicts. This shows up in the Linux file system

__*ls /sys/firmware/devicetree/base/reserved-memory/*__

.

sample-memory@90000000

You may be able to use the same address. If it is not available your board will crash on boot up. I made a couple of SD cards to boot from. you don’t want to modify the mmc files until you know it will boot cleanly. Otherwise, you will have to reflash the MMC and that is a pain.

Hope this helps.

This email is intended solely for the use of the individual to whom it is addressed and may contain confidential and/or privileged material. Any views or opinions presented are solely those of the author and do not necessarily represent those of Precision Planting. If you are not the intended recipient, be advised that you have received this email in error and that any use, dissemination, forwarding, printing, or copying of this email is strictly prohibited. Neither AGCO nor the sender accepts any responsibility for viruses, and it is your responsibility to scan, and virus check the e-mail and its attachment(s) (if any).