Use 32-bit (or smaller) naturally aligned values in the PRU data ram and
accesses will be atomic on both the PRU and the ARM side.
// Address 0x10000 is refered to as "shared data" in the PRU local data memory map.
volatile unsigned int* shared_ram = (volatile unsigned int *)0x10000;
shared_ram[100] = 0xFFFF;
void* p;
prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, &p);
shared_ram = (volatile unsigned int*)p;
unsigned int foobar = shared_ram[100];
/////////////////////////////////////////////////////////////////////
// Ring buffer.
//
// Communication with PRU is through a ring buffer in the
// PRU shared memory area.
// shared_ram[0] to shared_ram[127] is the buffer data.
// shared_ram[128] is the start (read) pointer.
// shared_ram[129] is the end (write) pointer.
//
// Messages are 32 bit unsigned ints.
//
// Read these:
// * http://en.wikipedia.org/wiki/Circular_buffer#Use_a_Fill_Count
// * https://groups.google.com/forum/#!category-topic/beagleboard/F9JI8_vQ-mE
static volatile unsigned int* shared_ram = NULL;
void* p;
prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, &p);
shared_ram = (volatile unsigned int*)p;
unsigned int buffer_size;
volatile unsigned int *buffer_start;
volatile unsigned int *buffer_end;
void buffer_init(){
buffer_size = 128;
buffer_start = &(shared_ram[128]); // value inited to 0 in pru
buffer_end = &(shared_ram[129]); // value inited to 0 in pru
}
static inline int buffer_is_empty(){
return (*buffer_start == *buffer_end);
}
static inline void buffer_read(unsigned int* message){
*message = shared_ram[*buffer_start & (buffer_size-1)];
// Don't write buffer start before reading message (mem barrier)
// http://stackoverflow.com/questions/982129/what-does-sync-synchronize-do
// https://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier
__sync_synchronize();
// Increment buffer start, wrap around size
*buffer_start = (*buffer_start+1) & (2*buffer_size - 1);
}
void main(){
buffer_init();
unsigned int message;
while(!buffer_is_empty()){
buffer_read(&message);
}
}
/////////////////////////////////////////////////////////////////////
// RING BUFFER
//
// Communication with ARM processor is througn a ring buffer in the
// PRU shared memory area.
// shared_ram[0] to shared_ram[127] is the buffer data.
// shared_ram[128] is the start (read) pointer.
// shared_ram[129] is the end (write) pointer.
//
// Messages are 32 bit unsigned ints.
//
// Read these:
// * http://en.wikipedia.org/wiki/Circular_buffer#Use_a_Fill_Count
// * https://groups.google.com/forum/#!category-topic/beagleboard/F9JI8_vQ-mE
volatile unsigned int* shared_ram = (volatile unsigned int *)0x10000;
unsigned int buffer_size;
volatile unsigned int *buffer_start;
volatile unsigned int *buffer_end;
void init_buffer(){
// data in shared_ram[0] to shared_ram[127]
buffer_size = 128;
buffer_start = &(shared_ram[128]);
buffer_end = &(shared_ram[129]);
*buffer_start = 0;
*buffer_end = 0;
}
inline void buffer_write(unsigned int message){
shared_ram[*buffer_end & (buffer_size-1)] = message;
unsigned int is_full = (*buffer_end == (*buffer_start^buffer_size)); // ^ is orex
if(is_full){
// Increment buffer start, wrap around size
*buffer_start = (*buffer_start+1) & (2*buffer_size - 1);
}
// Increment buffer end, wrap around size
*buffer_end = (*buffer_end+1) & (2*buffer_size - 1);
}
void main(){
buffer_init();
buffer_write(0xff0000ff);
buffer_write(0x11335577);
//...
}
I would set a flag in shared memory stating the arm read a value from the ring buffer.
You then wait for the flag to clear before reading the next value.
The PRU would then change the ring buffer pointers and reset the flag.
The trick is for the PRU to be the only core manipulating the buffer pointers.
inline void buffer_write(unsigned int message){
unsigned int is_full = (*buffer_end == (*buffer_start^buffer_size)); // ^ is orex
if(!is_full){
shared_ram[*buffer_end & (buffer_size-1)] = message;
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
unsigned int is_full = (*buffer_end == (*buffer_start^buffer_size));
int buffer_is_empty(){
return (*buffer_start == *buffer_end);
}
*buffer_start = (*buffer_start+1) & (2*buffer_size - 1);
*buffer_end = (*buffer_end+1) & (2*buffer_size - 1);