I'm using ZYNQ 7000 and implementing a counter in a bare-metal system. A counter in the shared memory is increased by both cores. _Atomic is used so that the 2 cores can be synchronized. But accessing the atomic variable results in dead loop.
The code
// shared_mem.h #include <stdint.h> #define SHARED_MEM_BASE_ADDR 0xffff0000 typedef struct { uint32_t basicCounter; _Atomic uint32_t atomicCounter; } SharedMem; #define SHAERD_MEM ((volatile SharedMem *)SHARED_MEM_BASE_ADDR) // main.c, core0 and core1 #include "shared_mem.h" int debuggerflag = 0; // set to 1 by debugger, each core has one flag #define INC_VALUE 10000 void IncreaseCounters(){ for(unsigned i=0; i< INC_VALUE; ++i){ ++SHAERD_MEM->basicCounter; } for(unsigned i=0; i< INC_VALUE; ++i){ ++SHAERD_MEM->atomicCounter; // blocks here if Xil_SetTlbAttributes(0xffff0000, 0x14de2); has been called } } int main(){ for(;;){ if(debuggerflag) { IncreaseCounters(); debuggerflag = 0; } } }
The problem I met:
dmb ish ; data memory barrier .L2: ldrex r3, [r0] ; exclusive load, r3=*r0 add r3, r3, #1 ; increment strex r2, r3, [r0] ; exclusive store, *r0=r3, write result in r2 cmp r2, #0 ; r2==0 means exclusive store succeeds bne .L2 ; retry if fails dmb ish
Is this a config problem of MMU? How can the counter be synchronized in the 2 cores? Thanks very much
The debugger shows cp15.c1.scltr is 0x08c5187d, TRE bit is 0, TEX remap is not enabled. Both of the attributes work (the second argument of Xil_SetTlbAttribute being 0x15de6 or 0x17dee), thanks so much!