Problems in using PRU on BeagleBone

I have mostly made a FFT analyzer from a BBB. There are up to 3 LTC2500 ADCs sampling analog

data at 1MSPS, 32 Bits per sample. I got my Agilent 89441A back to work, therefore this here is idle

for >> 1 year. I started that with PRU0, but PRU1 has more usable pins.

PRU 1 was reading the data with the help of an external CPLD that converted SPI to Bytes since even

the PRU could not read SPI at 3*100 MBit. There is a 12 KB dual port buffer somewhere accessible to

both the ARM and the PRU. The lowest words of the buffer make a command/status interface between

ARM and PRU (command, status, 3 parameters, 3 test results, etc). The rest of the buffer is used to

transfer long time series to the ARM in a ping-pong way. (The way I used it.)

The shared buffer has a fixed address on the PRU side, and also on the ARM side. You cannot use

this address in your ARM program but you can mmap() it into the virtual memory space of the ARM.

That is a standard system call.

The following source code was not meant for publication, it is half-done. Don't hit me too hard.

But the access to the shared ram works from both sides, this here is the ARM side.

It seems you have the PRU side already. What you need is probably openpru().

Sorry for the semi-German in the source.

regards, Gerhard

Gehard, thank you very much!

Considering the code you’ve provided, I understand that:

  • I need these header files:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include “ltcsrv.h”
#include “pru_if.h”

  • A file descriptor must be used for /dev/mem:

int dev_mem_fd;
dev_mem_fd = open("/dev/mem",O_RDWR | O_SYNC);

  • Shared RAM is mapped (prepared for use) by this line:

shared_ram = (int ) mmap(NULL, 121024, PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, 0x4A300000 + 0x10000);

  • Here follows examples of usage (in this case, writing to shared ram memory):

shared_ram[0] = … ; //write to 0x4A310000
shared_ram[1] = … ; //write to 0x4A310004
shared_ram[1] = … ; //write to 0x4A310008

Am I right?

Regarding header files, I noticed the pru related headerfile has been included as #include “pru_if.h”. Is it a local file from your project or a header file referred to a lib? In case of being referred to a lib, it could be included as #include <pru_if.h>, right?

Best Regards,
Pedro Bertoleti

Hi,

just for the mapping, you won’t need most of the include files.

I often include xyz.h in xyz.c so that I get at least a warning when I change

sth. so that the public promises in .h no longer hold.

pru_if.h is in the post but not needed.

Remove the includes and the compiler will tell you what is missing.

You definitely don’t need ltcsrv.h and the stuff for nice().

  • A file descriptor must be used for /dev/mem:

int dev_mem_fd;
dev_mem_fd = open(“/dev/mem”,O_RDWR | O_SYNC);

  • Shared RAM is mapped (prepared for use) by this line:

shared_ram = (int ) mmap(NULL, 121024, PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, 0x4A300000 + 0x10000);

  • Here follows examples of usage (in this case, writing to shared ram memory):

shared_ram[0] = … ; //write to 0x4A310000
shared_ram[1] = … ; //write to 0x4A310004
shared_ram[1] = … ; //write to 0x4A310008

^!!

Am I right?

Yes.

I should have snipped a lot of text, but was only half awake.

Cheers, Gerhard

One detail,

If I not wrong, the first 100 bytes of the dram is used by pru for some configs, register and other stuffs I don’t remember right now, so you should use BASE Address +1000 at least

https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf?ts=1610923856664 - section 4.3 details the memory usage from PRU.

Vinicius, have you meant 0x4A300000 + 0x1000 as the frist shared mem address to be used?

Probably PRU-owned SRAM, not the global DRAM.

The 12 KB shared ram is free to use, the ARM and the PRU program just must agree.

Each PRU has 2 KB static ram intended for itself, it can also be seen by the other PRU

and by the ARM. The C compiler uses that for variables, stack and heap.

When you use the functions copy_pru_ram_to_file() and copy_shared_ram_to_file()

you can open the file with vi or whatever and see the RAM contents in a slightly

annotated form. It's not a symbolic debugger but better than nothing.

Gerhard

Hi Pedro,

Yes

Vinicius and Gehard, thank you very much for your help!

I’m able to communicate (through shared memory) PRU0 and host (Linux) side. It worked really well!

Hi Pedro,

nice :slight_smile: