I'm using an ADSP-SC573. I would like to be able to test and set a byte atomic from the other cores.This byte is located in L2 RAM so it can be shared by all cores. Is thera a way to do it in ARM and SHARC cores?
I think the Blackfin had a testset function but I can't find any for the ARM and SHARC.
I found how to accuire a lock in the SHARC DSP at least:
void acquireLock(volatile uint8_t *lock) { while (true) { int err; int locked = load_exclusive_8((unsigned volatile char *)lock, &err); if (err != 0) continue; if (locked == 0) { err = store_exclusive_8(1, (unsigned volatile char *)lock); if (err == 0) break; } } } void releaseLock(volatile uint8_t *lock) { while (true) { int err; int locked = load_exclusive_8((unsigned volatile char *)lock, &err); if (err != 0) continue; if (locked == 1) { err = store_exclusive_8(0, (unsigned volatile char *)lock); if (err == 0) break; } } }
For the ARM core I would need to write C/assembly that uses the LDREXB and STREXB instructions. Any tips on how to do that?
NOte: Later I found some code for LDREXB and STREXB at https://github.com/ARM-software/CMSIS/blob/master/CMSIS/Include/cmsis_gcc.h that I tried on the ARM:
/** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ uint8_t __LDREXB(volatile uint8_t *addr) { uint32_t result; asm volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); return (uint8_t) result; } /** \brief STR Exclusive (8 bit) \details Executes a exclusive STR instruction for 8 bit values. \param [in] value Value to store \param [in] ptr Pointer to location \return 0 Function succeeded \return 1 Function failed */ uint8_t __STREXB(uint8_t value, volatile uint8_t *addr) { uint32_t result; asm volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); return (uint8_t)result; } void acquireLock(volatile uint8_t *lock) { while (true) { uint8_t locked = __LDREXB(lock); if (locked == 0) { uint8_t err = __STREXB(1, lock); if (err == 0) break; } } } void releaseLock(volatile uint8_t *lock) { while (true) { uint8_t locked = __LDREXB(lock); if (locked == 1) { uint8_t err = __STREXB(0, lock); if (err == 0) break; } } }
Added code for ARM
[edited by: masip at 2:01 PM (GMT -4) on 24 Oct 2022]