Problem with validity of data written to reserved memory by pru

Hello. I have a problem with writing data to reserved memory by PRU in BeagleBone Black.
Reserving memory is done through device tree “reserved-memory” node. The memory is reserved correctly and I can see the gap in the System Ram in “/proc/iomem” file.
I want PRU to write data items to the reserved memory and an user-space C program running on Linux will read these data items.
The problem is that some of the data items have not written to the reserved memory correctly. For example, if I write 100 integer numbers to the reserved memory, the numbers between 39 and 47 will not be written correctly while the other integers are written correctly. In other words, when I read the integer numbers from the reserved memory, all the integer numbers are correct, but numbers in the rage 40 to 62 are not correct.

reserved_memory_problem.jpg

In the above picture, numbers in the left column are the indexes of data in the reserved memory and numbers in the right column are the values of data items stored in the reserved memory. All values are correct but values in the range 39 to 47 are not correct. The contents of reserved memory are read using “devmem2”.

Does anyone know why that chunk of data (39 to 47) is not written correctly by the PRU?

Did you flag the reserved memory as non-cachable?

If not, add the "no-map" property to your device tree node, or
otherwise manage the cache (which typically requires root permissions
and kernel mode code):

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

Hello Charles. Thank you for your reply.

Yes, I had flagged the reserved memory as non-chachable using “no-map” property in device tree. Indeed, the mentioned problem exists while the reserved-memory is non-chachable.

On Sat, 29 Dec 2018 11:42:49 -0800 (PST),
dehghanialif@gmail.com declaimed the
following:

Yes, I had flagged the reserved memory as non-chachable using "no-map"
property in device tree. Indeed, the mentioned problem exists while the
reserved-memory is non-chachable.

  Is there any possibility you are encountering a race condition? The
user-land program possibly reading parts of memory that haven't yet been
written by the PRU (and then getting pre-empted long enough for the PRU to
write to the rest of memory before the user-land process runs and completes
reading memory).

Hello Dennis.
No. I think there is no possibility to occur race condition. Because I just write the data once and read the data after a while (about a few seconds).

Some points to note:

  1. The number of invalid data items varies after rebooting the os and running PRU again. In the next tries (without rebooting the os), the number of invalid data items is the same.
  2. Invalid data items are continuous in the memory space.
  3. The offset of invalid data items in the memory varies after rebooting the os and running PRU again. In the next tries (without rebooting the os), the offset of invalid data items is the same.
  4. The value of invalid data items in the memory varies after rebooting the os and running PRU again. In the next tries (without rebooting the os), the value of invalid data items is the same.

This is my c source which runs on the PRU and writes data to the reserved-memory:

#include <stdint.h>
#include <pru_cfg.h>
#include <string.h>
#include “resource_table_empty.h”

#define RESERVED_MEMORY_OFFSET 0x80400000
#define RESERVED_MEMORY_RANGE 0x00100000

void main(void)
{
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;

uint32_t *ptr = (volatile uint32_t ) RESERVED_MEMORY_OFFSET;
uint32_t wrData[200];
uint32_t ind;
for(ind=0; ind<200; ind++){
wrData[ind] = ind;
}
memcpy(ptr, wrData, 200
sizeof(uint32_t));

while(1);
__halt();
}

This is the C source which I run in the os to read data items in the reserved memory:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>

#define RESERVED_MEMORY_OFFSET 0x80400000
#define RESERVED_MEMORY_RANGE 0x00100000

int main(void)
{
int ret;
int fd = open("/dev/mem", O_RDWR|O_SYNC);
if(fd < 0){
printf(“Unable to open /dev/mem\n”);
return -1;
}

void *ptr = (void *) mmap(0, RESERVED_MEMORY_RANGE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RESERVED_MEMORY_OFFSET);
if(ptr==NULL){
printf(“Cant mmap\n”);
return -2;
}

uint32_t rdData[RESERVED_MEMORY_RANGE];
uint32_t ind;
memcpy(rdData, ptr, RESERVED_MEMORY_RANGE);
for(ind=0; ind<200; ind++){
printf("%d\t\t%u\n", ind, rdData[ind]);
}
return 0;
}