On 10/13/2016 5:48 PM, Jay Doobie wrote:
> Hi,
>
> I'm trying to send some data from ARM to the PRU for the PRU to execute upon it,
> but I'm having some issues where it tends to miss some of the data on the PRU,
> so I assume I am not synchronizing the interrupts properly, here is basically
> what I am doing:
>
> C code:
>
> for (i = 0; i < 10; i++) {
> prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, SHARED_MEMORY, (unsigned
> int*)pkts[i], memSize);
> //if I put a sleep here it generally works: usleep(500000);
The ARM has a weak memory model. You need a memory fence instruction
here to insure that all writes before the fence (your write to the PRU
memory, above) have completed before any writes after the fence
(generating the PRU interrupt) take effect.
It's a bit ham-fisted, but you can use a __sync_synchronize() here
(assuming you're using gcc...it's a full memory barrier). Or you can
use the C++11 memory fence semantics (more complicated). Either is
way better than the "old school" full cache flush and invalidate! :)
> //printf("sending intc...\n");
> // here are the packets!
> prussdrv_pru_send_event(ARM_PRU0_INTERRUPT);
> // wait for PRU response
> //printf("waiting intc...\n");
> prussdrv_pru_wait_event (PRU_EVTOUT_0);
> // clear PRU response
> //printf("clr intc from PRU0...\n");
> prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
>
> }
>
> PRU:
>
> HANDLE_DATA:
> // wait for interrupt
> WBS r31, #30
> // reset interrupt
> LBCO r20, CONST_IEP, 0x44, 4 // Load CMP_STATUS register
> sbco rResetInterrupt, CONST_PRUSSINTC, SICR_OFFSET, 4
> // handle data
> MOV R31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
> sub rCounter, rCounter, rCounter
> qbne HANDLE_DATA, rCounter, 0
>
>
> Kernel: Linux beaglebone 3.8.13-bone79 #1 SMP Tue Oct 13 20:44:55 UTC 2015
> armv7l GNU/Linux
>
> Thanks!
--
Charles Steinkuehler
cha...@steinkuehler.net