Strange behavior of value returned from PRU with RPMSG

I am using a Beaglebone Black and C to read analog inputs with PRU0 and return the data to a host program using RPMSG.

Basically, I read the data from FIFO0 fine, strip the step id from it and copy it into an element of a character array in the PRU code.


if ((Data & 0x000F0000) == 0) { // checking the step id tag for step 0
// if step == 0, strip off the step and put the data in array DetBSample
DetBSample[sampleno] = Data & 0xFFF;

memcpy(payload, “\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0”, 24); // this came from TI’s sample code, best I can tell it just preloads and end of string character in the whole string.
ltoa((long)DetBSample[sampleno], payload); // put the value in DetBSample[sampleno] in the character string payload
// now send the payload to the host
pru_rpmsg_send(&transport, dst, src, payload, 24);

This code compiles and runs fine.

On the host side, I do this when I’m kicked by the PRU. (This is a snippet so brackets may not match!)

/* Poll until we receive a message from the PRU and then print it */
result = read(pollfds[0].fd, readBuf, MAX_BUFFER_SIZE);
if (result > 0)
Volts = atof(readBuf)*ADC_Res;
printf(“Message %d received from PRU:%s or %x\n”, i, readBuf, readBuf);
printf(“Volts read: %.3f\n”,Volts);

The output is strange though (snippet below). The message #, string value of readBuf and Volts are all correct. But when I output readBug as hex, it never changes. I thought it might be the address of readBuf but it doesn’t appear to be.

The voltage matches the input we’re providing from a bench power supply and the decimal value is correct. It’s just that this hex value doesn’t change.

Message 97 received from PRU:3742 or 4b50b0
Volts read: 1.644
Message 98: Sent to PRU
Message 98 received from PRU:3744 or 4b50b0
Volts read: 1.645
Message 99: Sent to PRU
Message 99 received from PRU:3743 or 4b50b0
Volts read: 1.645
Received 100 messages, closing /dev/rpmsg_pru30

Hello Walter

I didn’t see your definition of readBuf.why you expecting an address to change?
I am glad you found the TI examples helpful.


Here is the definition

char readBuf[MAX_BUFFER_SIZE];


I think I may have just realized why this is occurring. When %s refers to readBuf it will output the value in the character array. But %x is outputting the address of it.

Duh…not the first dumb mistake I’ve made today.

Hello Walter

Not dumb you have done well I’m taking credit🤣 for your sucess just kidding.I saw a bunch of good examples somewhere maybe SDK.
What was cool was they had PRU code that used every peripheral possible from the PRU. Excellent starting point the TI examples combined with Cookbook you have something going!!! and choices.

I’m off trying to run something similar on the ARM using CCS and starterware and JTAG on a beaglebone white. I realize that’s unrelated to your goals but I also got up to speed quickly you inspired me to refresh my skills.
Thank you!!!



Try changing the %n in the print statement to print out a 32 bit value. I think you will see that it is an address in the PRU address space.


I’m working on that very thing. I fairly certain what is printing is an address although it doesn’t seem to correspond to anything I’d expect.

Dump or print the quantity pointed at if you’re intrigued to see if it’s correct.

For all who want to learn:

Walter is formating a human readable number in the PRUSS code (function ltoa).

How much PRU cycles does a four digit number need? And how much are necessary for a one digit number?

Note: The PRUSS are fine for realtime solutions (if your code allows that).

Welcome to rproc/rpmsg - you completely lost track.

Clock cycle’s good subject. Seems some thinks everything PRU does is one clock cycle ( 5ns) perhaps assembler instructions are. Also confusion about actual speed of control loops.
A 100ns control loop runs every 100ns and does input, decisions and output that fast. Lastly the PRU has small codes size and any fast control loop running on ARM must get the data from PRU quickly. I know you understand these concept.

My solution to the original question Walter posted is now working.
I used bare metal on arm in system mode.
CCS and JTAG to debug the ARM samples ADC. Input to ARM control loop comes from GUI on PC. No delays took about 8 hour’s coding. No IPC.

Your project sound’s interesting I will be watching for an ARM to PRU ADC examples using libruio and current Linux provided by this group. Just downloaded and go :+1:

You are correct to mention this TJF. In production, I won’t bother to do convert it to a human-readable number. It helps with debugging right now though.

And for debugging purposes, is it a good idea to convert at PRU side? From
my point of view the CCS and rproc/rpmsg concepts are dangerously