Beaglebone Black [BBB] Read Shared memory from PRU

196 views
Skip to first unread message

marcu...@gmail.com

unread,
Mar 12, 2019, 12:54:06 PM3/12/19
to BeagleBoard

i wrote a PRU Programm where i read some Sensors and calculate something. Then i save the Data in the shared RAM.

But how can i read the memory from the ARM? is it possible to read it from an c programm or shell? edit: i programm the PRU with this method: https://markayoder.github.io/PRUCookbook/index.html

Greetings Marcus

Gerhard Hoffmann

unread,
Mar 12, 2019, 1:31:00 PM3/12/19
to beagl...@googlegroups.com


Am 12.03.19 um 16:43 schrieb marcu...@gmail.com:

i wrote a PRU Programm where i read some Sensors and calculate something. Then i save the Data in the shared RAM.

But how can i read the memory from the ARM? is it possible to read it from an c programm or shell? edit: i programm the PRU with this method: https://markayoder.github.io/PRUCookbook/index.html

Greetings Marcus


That is experimental code I have not seen for some months (must first do the hardware)

It shows how to mmap the PRU / shared ram into the ARM memory space and dump the contents to files.

The dumps are somewhat annotated with the data structures I use.

This is ad hoc ripped from the source files, not intended to be compiled as it is.



#include <sys/types.h>        /* type definitions used by many programs */
#include <stdio.h>            /* standard IO functions */
#include <stdlib.h>            /* commonly used functions, EXIT_SUCCESS and EXIT_FAILURE */
#include <errno.h>
#include <string.h>
#include <math.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#include "ltcsrv.h"        /* for panic() */
#include "pru_if.h"        /* to enforce consistency with .c */

#include "cmnd_stat_codes.h"


#define ADC_BUFFER_SIZE    (16*1024)

int                dev_mem_fd;
volatile int    *shared_ram;
volatile int    *pru_ram;            // the 8 KB local data = 2 KWORDS
int                adc_buffer[ADC_BUFFER_SIZE];
int                cmnd_to_send;




int open_pru(){

    int i;

    //if (verbose) printf("enter open_pru()\n");
    if (init_cpld_pins()) return 1;

    //if(verbose) printf("starting pru 0\n");
//    if (!start_pru()) return 1;
//    printf("sleeping 1 s\n");
//    sleep(1);

    // map the shared ram into our virtual memory
    //printf("mapping...\n");
    dev_mem_fd = open("/dev/mem",O_RDWR | O_SYNC);

    // mmap params: 
    // addres where the kernel creates the mapping. NULL= do as you like
    // size of the mapped region  12288 = 12 KBytes
    // protection
    // flags
    // file descriptor von /dev/mem
    // pru-base  = 0x4A30_0000, shared ram starts at +0x10000
    shared_ram = (int *) mmap(NULL, 12*1024, PROT_READ | PROT_WRITE, MAP_SHARED,
                dev_mem_fd, 0x4A300000 + 0x10000);
    if (-1 == (int)shared_ram) panic("could not mmap() shared PRU ram");

    // both PRU local data rams together
    pru_ram = (int *) mmap(NULL, 2*8*1024, PROT_READ | PROT_WRITE, MAP_SHARED,
                dev_mem_fd, 0x4A300000 + 0x00000);
    if (-1 == (int)pru_ram) panic("could not mmap() local PRU rams");


    for (i=0; i< ADC_BUFFER_SIZE; i++){   // 12 KB are 3 Kwords
        adc_buffer[i] = 0;
    }

    return 0;
}

int close_pru(void){
    // FIXME: shared RAM must be un-mapped and file descriptors should be closed
    if (verbose) printf("enter close_pru()\n");
//    if (!stop_pru()) return 1;
    if (verbose) printf("leaving close_pru()\n");
    return 0;
}


void copy_shared_ram_to_file(char *fn){

    FILE * phyle;
    int i, j;

    phyle = fopen(fn, "w");        // FIXME return value
    fprintf(phyle, "%s\n", fn);
    fprintf(phyle, "byte index dec byte index hex  word index  content\n\n");
    for (i=0; i< 3*1024; i++){   // 12 KB are 3 Kwords
        fprintf(phyle, "\n%12d   %8x   %8x  = 0x%8x    %12d", 4*i, 4*i, i, shared_ram[i], shared_ram[i]);
        switch(i){
            case 0:                fprintf(phyle, "  unused"); break;
            case COMMAND:        fprintf(phyle, "  command"); break;
            case STATUS:        fprintf(phyle, "  status"); break;
            case PARAM1:        fprintf(phyle, "  param1"); break;
            case PARAM2:        fprintf(phyle, "  param2"); break;
            case PARAM3:        fprintf(phyle, "  param3"); break;
            case TEST1:            fprintf(phyle, "  test1"); break;
            case TEST2:            fprintf(phyle, "  test2"); break;
            case TEST3:            fprintf(phyle, "  test3"); break;
            case PING_FULL:        fprintf(phyle, "  ping_full"); break;
            case PONG_FULL:        fprintf(phyle, "  pong_full"); break;
            case PING:            fprintf(phyle, "  ping buffer start"); break;
            case PONG:            fprintf(phyle, "  pong buffer start"); break;
        }
    }
    fclose(phyle);      // FIXME return value
}


// thats for all the  2*8 KBytes
void copy_pru_ram_to_file(char *fn){

    FILE * phyle;
    int i, j;

    phyle = fopen(fn, "w");        // FIXME return value
    fprintf(phyle, "%s\n", fn);
    fprintf(phyle, "byte index  word index  content   all hex\n\n");
    fprintf(phyle, "stack lowest and data nil pointer\n");

    for (i=0; i< 4*1024; i++){   // 2 * 8 KB are 4 Kwords

        if      (0x100/4 == i)    { fprintf(phyle, "\nstack highest - heap lowest\n"); }
        else if (0x200/4 == i)    { fprintf(phyle, "\nheap highest\n"); }

        fprintf(phyle, "%8x   %8x = %8x\n", 4*i, i, pru_ram[i]);

    }
    fclose(phyle);      // FIXME return value
}

hope it helps somewhat.

regards,

Gerhard




Mark A. Yoder

unread,
Mar 13, 2019, 10:57:39 AM3/13/19
to BeagleBoard
The PRU Cookbook has an exampled of writing shared memory with the ARM.


--Mark

Walter Cromer

unread,
Apr 29, 2021, 3:15:10 PM4/29/21
to BeagleBoard
Mark - I'm integrating the concepts from the PRUCookbook so I can send some control parameters entered by the user in the host side program and pass them over to the PRU0 firmware.

I'm getting this error when I try to compile the code.

Setting up pru0 memory access.
ERROR: could not open /dev/mem.

Any ideas?

I'm running a BBB Wireless with video and audio disabled.

Here's the output of version.sh

debian@beaglebone:/var/lib/cloud9$ sudo /opt/scripts/tools/version.sh
[sudo] password for debian:
git:/opt/scripts/:[b39ec679648a6be8f25f48bd1c9784c1fc5a0c46]
eeprom:[A335BNLTBWA52027BBWG0227]
model:[TI_AM335x_BeagleBone_Black_Wireless]
dogtag:[BeagleBoard.org Debian Buster IoT Image 2020-04-06]
bootloader:[microSD-(push-button)]:[/dev/mmcblk0]:[U-Boot 2019.04-00002-g07d5700e21]:[location: dd MBR]
bootloader:[eMMC-(default)]:[/dev/mmcblk1]:[U-Boot 2018.03-00002-gac9cce7c6a]:[location: dd MBR]
UBOOT: Booted Device-Tree:[am335x-boneblack-uboot-univ.dts]
UBOOT: Loaded Overlay:[AM335X-PRU-RPROC-4-19-TI-00A0]
UBOOT: Loaded Overlay:[BB-ADC-00A0]
UBOOT: Loaded Overlay:[BB-BBBW-WL1835-00A0]
UBOOT: Loaded Overlay:[BB-BONE-eMMC1-01-00A0]
UBOOT: Loaded Overlay:[BB-I2C2-RTC-DS3231]
UBOOT: Loaded Overlay:[BB-W1-P9.12-00A2]
kernel:[4.19.94-ti-r61]
nodejs:[v10.15.2]
/boot/uEnv.txt Settings:
uboot_overlay_options:[enable_uboot_overlays=1]
uboot_overlay_options:[uboot_overlay_addr4=/lib/firmware/BB-W1-P9.12-00A0.dtbo]
uboot_overlay_options:[disable_uboot_overlay_video=1]
uboot_overlay_options:[disable_uboot_overlay_audio=1]
uboot_overlay_options:[uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo]
uboot_overlay_options:[enable_uboot_cape_universal=1]
uboot_overlay_options:[dtb_overlay=/lib/firmware/BB-I2C2-RTC-DS3231.dtbo]
pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]
pkg:[bb-cape-overlays]:[4.14.20210401.0-0~buster+20210401]
pkg:[bb-wl18xx-firmware]:[1.20200322.0-0rcnee0~buster+20200322]
pkg:[kmod]:[26-1]
pkg:[librobotcontrol]:[1.0.4-git20190227.1-0rcnee0~buster+20190327]
pkg:[firmware-ti-connectivity]:[20190717-2rcnee1~buster+20200305]
groups:[debian : debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal bluetooth netdev i2c gpio pwm eqep remoteproc admin spi iio docker tisdk weston-launch xenomai cloud9ide]
cmdline:[console=ttyO0,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 quiet]
dmesg | grep remote
[   69.927418] remoteproc remoteproc0: wkup_m3 is available
[   70.105672] remoteproc remoteproc0: powering up wkup_m3
[   70.105706] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 217148
[   70.106000] remoteproc remoteproc0: remote processor wkup_m3 is now up
[   72.319951] remoteproc remoteproc1: 4a334000.pru is available
[   72.335870] remoteproc remoteproc2: 4a338000.pru is available
[  564.302719] remoteproc remoteproc1: powering up 4a334000.pru
[  564.303391] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 118908
[  564.316303] remoteproc remoteproc1: registered virtio0 (type 7)
[  564.316324] remoteproc remoteproc1: remote processor 4a334000.pru is now up
[  590.322924] remoteproc remoteproc1: stopped remote processor 4a334000.pru
[  594.762821] remoteproc remoteproc1: powering up 4a334000.pru
[  594.763533] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 118888
[  594.777049] remoteproc remoteproc1: registered virtio0 (type 7)
[  594.777060] remoteproc remoteproc1: remote processor 4a334000.pru is now up
dmesg | grep pru
[   72.319951] remoteproc remoteproc1: 4a334000.pru is available
[   72.320135] pru-rproc 4a334000.pru: PRU rproc node pru@4a334000 probed successfully
[   72.335870] remoteproc remoteproc2: 4a338000.pru is available
[   72.336020] pru-rproc 4a338000.pru: PRU rproc node pru@4a338000 probed successfully
[  564.302719] remoteproc remoteproc1: powering up 4a334000.pru
[  564.303391] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 118908
[  564.304236] pruss 4a300000.pruss: configured system_events[63-0] = 00000000,00030000
[  564.304251] pruss 4a300000.pruss: configured intr_channels = 0x00000005 host_intr = 0x00000005
[  564.316324] remoteproc remoteproc1: remote processor 4a334000.pru is now up
[  564.391508] virtio_rpmsg_bus virtio0: creating channel rpmsg-pru addr 0x1e
[  564.467856] rpmsg_pru virtio0.rpmsg-pru.-1.30: new rpmsg_pru device: /dev/rpmsg_pru30
[  590.322860] pruss 4a300000.pruss: unconfigured system_events[63-0] = 00000000,00030000
[  590.322880] pruss 4a300000.pruss: unconfigured host_intr = 0x00000005
[  590.322924] remoteproc remoteproc1: stopped remote processor 4a334000.pru
[  594.762821] remoteproc remoteproc1: powering up 4a334000.pru
[  594.763533] remoteproc remoteproc1: Booting fw image am335x-pru0-fw, size 118888
[  594.764695] pruss 4a300000.pruss: configured system_events[63-0] = 00000000,00030000
[  594.764710] pruss 4a300000.pruss: configured intr_channels = 0x00000005 host_intr = 0x00000005
[  594.775769] virtio_rpmsg_bus virtio0: creating channel rpmsg-pru addr 0x1e
[  594.776757] rpmsg_pru virtio0.rpmsg-pru.-1.30: new rpmsg_pru device: /dev/rpmsg_pru30
[  594.777060] remoteproc remoteproc1: remote processor 4a334000.pru is now up
dmesg | grep pinctrl-single
[    0.952360] pinctrl-single 44e10800.pinmux: 142 pins, size 568
dmesg | grep gpio-of-helper
[    0.965863] gpio-of-helper ocp:cape-universal: ready
lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
END

Walter Cromer

unread,
Apr 29, 2021, 3:17:16 PM4/29/21
to BeagleBoard
Here's the code too.   Sorry, should have included it.

int fd;
    printf("Setting up pru0 memory access.\n");

    fd = open ("/dev/mem", O_RDWR | O_SYNC);
    if (fd == -1) {
        printf ("ERROR: could not open /dev/mem.\n\n");
        return 1;
    }


When I look for /dev/mem it doesn't exist whether logged in as debian or root

Mark A. Yoder

unread,
Apr 29, 2021, 4:04:42 PM4/29/21
to BeagleBoard
Are you sure /dev/mem isn't there?  I think it's required.

bone$ ls -ls /dev/mem
0 crw-r----- 1 root kmem 1, 1 Apr 14 09:11 /dev/mem
bone$ groups
debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal input bluetooth netdev i2c remoteproc eqep pwm cloud9ide xenomai weston-launch tisdk docker iio spi admin gpio

You should be in the kmem group by default so sudo isn't needed.

--Mark

Walter Cromer

unread,
Apr 30, 2021, 10:06:42 AM4/30/21
to BeagleBoard
Well, yes indeed, it is there this morning.  I'll retry the code later and get back to you.

Walter Cromer

unread,
Apr 30, 2021, 11:22:10 AM4/30/21
to BeagleBoard
Mark ,

pwm4.pru0.c compiles fine from a command line in PUTTY using make TARGET=pwm4.pru0

When I try to run pwm_test.c within the cloud9 IDE I get this message from the program.  

Compiling /var/lib/cloud9/PRUCookbook/docs/05blocks/code/pwm-test.c ...
/var/lib/cloud9/common/Makefile:28: MODEL=TI_AM335x_BeagleBone_Black_Wireless,TARGET=,COMMON=/var/lib/cloud9/common
make: 'pwm-test' is up to date.
Servo tester
ERROR: could not open /dev/mem.

I checked with ls -ls /dev/mem logged in as debian and it's there.

Any ideas?

Dennis Lee Bieber

unread,
Apr 30, 2021, 12:23:43 PM4/30/21
to Beagleboard
On Fri, 30 Apr 2021 08:22:10 -0700 (PDT), in
gmane.comp.hardware.beagleboard.user Walter Cromer
<walterc-2dFtBuzUeF/tpnMUCzy8b...@public.gmane.org> wrote:


>I checked with ls -ls /dev/mem logged in as debian and it's there.
>
debian@beaglebone:~$ ls -ls /dev/mem
0 crw-r----- 1 root kmem 1, 1 Apr 30 12:06 /dev/mem
debian@beaglebone:~$
debian@beaglebone:~$ groups
debian adm kmem dialout cdrom floppy audio dip video plugdev users
systemd-journal input bluetooth netdev i2c remoteproc eqep pwm cloud9ide
xenomai weston-launch tisdk docker iio spi admin gpio
debian@beaglebone:~$


That is what my BBB shows.

Owner (root) has R/W permission
Group (kmem) has Read-Only permission.

The debian account has kmem group access.

From your earlier post...

> fd = open ("/dev/mem", O_RDWR | O_SYNC);

... you are asking for R/W access -- which is not set for members of the
kmem group. What happens if you attempt to open /dev/mem for read-only
access?


--
Dennis L Bieber

Walter Cromer

unread,
May 3, 2021, 11:40:35 AM5/3/21
to BeagleBoard
I changed the code to this and get the same error.

fd = open ("/dev/mem", O_RDONLY | O_SYNC);   // not sure O_SYNC is necessary since this is a read-only open situation

Servo tester!!!
ERROR: could not open /dev/mem.

make: *** [/var/lib/cloud9/common/Makefile:173: start] Error 1
rm /tmp/cloud9-examples/pwm-test.o


Here's some info about my specific owner/group & permissions.

debian@beaglebone:/var/lib/cloud9$ ls -ls /dev/mem
0 crw-r----- 1 root kmem 1, 1 Apr 30 20:30 /dev/mem
debian@beaglebone:/var/lib/cloud9$ groups
debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal bluetooth netdev i2c cloud9ide xenomai weston-launch tisdk docker iio spi admin remoteproc eqep pwm gpio
debian@beaglebone:/var/lib/cloud9$ whoami
debian
debian@beaglebone:/var/lib/cloud9$

Reply all
Reply to author
Forward
0 new messages