-
Notifications
You must be signed in to change notification settings - Fork 194
Open
Labels
Description
I'm using ZYNQ 7000 and want to use spinlock to synchronize the two cores (baremetal). The problem is metal_spinlock_acquire loops forever.
The code of core0's main.c:
// some includes
#define SHARED_MEM_BASE_ADDR // an address of DDR or OCM unused by both cores' linkers, like 0x30000000 or 0xffff0000
typedef struct {
struct some_struct variable;
struct metal_spinlock lock;
} SharedMem;
#define SHARED_MEM ((volatile SharedMem *)SHARED_MEM_BASE_ADDR)
void protected_read(struct some_struct *s) {
metal_spinlock_acquire(&SHARED_MEM->lock);
*s = SHARED_MEM->variable;
metal_spinlock_release(&SHARED_MEM->lock);
}
int main() {
init_system();
metal_spinlock_init(&SHARED_MEM->lock);
wake_up_core1();
struct some_struct s;
for(;;) {
protected_read(&s);
// process data
// core1 is supposed to read and write to variable with lock too
}
}metal_spinlock_acquire compiles to this:
0: e3a02001 mov r2, #1 ; r2 = 1
4: f57ff05b dmb ish ; data memory barrier
8: e1d03f9f ldrexb r3, [r0] ; r3 = *r0, r0's type is struct metal_spinlock *, aka atomic_flag *
c: e1c01f92 strexb r1, r2, [r0] ; *r0 = r2 = 1, save status in r1
10: e3510000 cmp r1, #0 ; exclusive store succeed?
14: 1afffffb bne 8 <metal_spinlock_acquire+0x8> ; if not succeed, try again
18: e31300ff tst r3, #255 ; any bit set in r3? was the lock held by others?
1c: f57ff05b dmb ish
20: 1afffff7 bne 4 <metal_spinlock_acquire+0x4> ; if lock was held by others, try again
24: e12fff1e bx lrIn metal_spinlock_acquire, strexb always fails, so it loops forever, even when core1 is halted by a debugger and never accesses the lock.
I find this link that says ZYNQ 7000 doesn't support exclusive access of OCM. But the behavior is still the same if SHARED_MEM_BASE_ADDR is a DDR address. How to make spinlock work on ZYNQ 7000?
P.S.:
Xil_SetTlbAttributes(SHARED_MEM_BASE_ADDR, 0x14de2)is called in both cores' init function as in xapp1079, to mark the address as sharable-DUSE_AMP=1is added in core1's bsp