My question is: How do I send data in a multiprocessor safe way from the ARM CortexA8 to PRU0 via a FIFO queue?
(The data might just be a structure with two uint32_t's.)
The PRU cape demo doesn't seem to have any examples of communicating between the ARM and the PRU (other than loading an image :) )..
I am using CCSv6 and a Beaglebone Black with AM355X Starterware and a TI PRU cape with the PRU software support package.
I can recompile and run a Debug version of the PRU cape demo. Using the TI XDS100v2 USB debug probe I can connect to both the CortexA8 and PRU0 and single step both. All good.
To continue, I have set up an example based on the PRU cape demo "PRU_LED0" where the ARM C program requests the user to enter a period (in PRU clock ticks) which is sent to the PRU via a shared variable "shared" defined in the link.cmd file (see below). This works and I can change the PRU cape LED flashing period interactively.
To protect simultaneous access to "shared" by both the ARM and the PRU I thought I could use a simple spinlock mechanism noting the Sitara processors spinlock registers for atomic accesses.
However, when I try to access the spinlock registers (e.g. by using HWREG(0x480CA010) = 0x02;) I get an UndefInstHandler() error.
Any suggestions for ways to accomplish this basic communication task between the ARM and a PRU or to fix my spinlock problems with my approach would be very much appreciated.
Are there any relevant examples available?
Bryan
Some More Detail
The method I have used for setting up the shared buffer is as follows (any comments appreciated):
In the ARM C program, declare extern uint32_t shared[10];
In the ARM link cmd file:
MEMORY
{
MYSHARED_MEM : org = 0x80000000 len = 0x30
DDR_MEM : org = 0x80000030 len = 0x8000000-0x30 /* RAM 128MB*/
}
/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
SECTIONS
{
.text:Entry : load > 0x80000030
.text : load > DDR_MEM /* CODE */
.data : load > DDR_MEM /* INITIALIZED GLOBAL AND STATIC VARIABLES */
.bss : load > DDR_MEM /* UNINITIALIZED OR ZERO INITIALIZED */
/* GLOBAL & STATIC VARIABLES */
RUN_START(bss_start)
RUN_END(bss_end)
.const : load > DDR_MEM /* GLOBAL CONSTANTS */
.cinit : load > DDR_MEM
.stack : load > DDR_MEM HIGH //0x87FFF000 /* SOFTWARE SYSTEM STACK */
LED0_text: {PRU_LED0_image.obj(.text)} load > DDR_MEM run_start(LED0_INST)
LED0_data: {PRU_LED0_image.obj(.data)} load > DDR_MEM run_start(LED0_DATA)
MyShared: load > MYSHARED_MEM RUN_START(shared) RUN_SIZE(shared_size)
}
In the PRU_LED0 C program declare: volatile uint32_t pru_shared[10] __attribute__((cregister("DDR")));
(The PRU_LED0 link.cmd file remains unchanged).
Now, I thought I could use a spinlock to protect the accesses:
while (readlock()==1);
shared[0] = 57; // Or on the PRU pru_shared[0] = 37;
writelock(0);