On 10/19/2014 1:39 PM, Rafael Vega wrote:
> 
> 
>> 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. 
>>
> So, something like this will do the trick (for atomic access)? on the PRU:
> // 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;

Yes, something like that.  I program the PRU in assembly, but the C code
looks correct on visual inspection.  :)

Note that even for a simple unidirectional ring buffer like you're
proposing (one reader, one writer), you can potentially have problems
with memory access ordering.  This isn't an issue on the PRU side (no
cache and no out-of-order execution), but the ARM has a weak memory
model and just because you do something in your code like:

  read A
  read B
  write C

...doesn't mean the hardware won't actually do something like:

  read A
  write C
  read B

...which can be a problem if the "write C" updates your ring buffer
pointer and indicates that "data B" was read and consumed by the reader
thread.  You can probably just ignore the problem and things will likely
work fine (unless you've got a really small ring buffer and are
particularly unlucky), but the proper solution to this is to use memory
barriers.  You can see how this is done in the Kernel code, and you're
lucky enough that GCC now has intrinsics for handling this, so you no
longer need to write assembly code on the ARM side to make sure your
ring buffer will *ALWAYS* work properly.  :)

-- 
Charles Steinkuehler
[email protected]

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to