This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM5728: Exclusive memory access

Part Number: AM5728

Hi,

I'm writing bare metal A15 application.

I've been trying to implement exclusive DDR memory access to implement a ring buffer that could be written in the main loop and in the interrupt. I can't disable the interrupt. All the accesses to that memory are from single A15 core.

I'm using following functions to load and store value, and to check if the access was not exclusive:

// Exclusive load
uint32_t  LDREX(volatile uint32_t *addr)
{
    uint32_t res;
    asm volatile(
    "   ldrex   %0, [%1]\n"
    "   bx  lr"
          : "=&r" (res) /* %0 put output to res. Don't overlap the register with the register used for variable addr */
          : "r" (addr));   /* %1 use addr as pointer*/
    return res;
}



// store value exclusively to the given address.
// return 0 if success
uint32_t STREX(uint32_t value, uint32_t *addr)
{
    uint32_t res=0;
    asm volatile ("strex %0, %2, [%1]" : "=&r" (res) : "r" (addr), "r" (value) );
    return res;
}

However. The first call to LDREX causes the Abort exception. I have tried different MMU settings: non shareable, shareable inner and shareable outer, but non of them does the trick.

What could be the reason for that? 

Is there some other, recommended and implemented way to implement such exclusivity check on A15?

  • Hi,

    Your query has been assigned to a TI engineer. Please note that feedback may be delayed due to holidays in the USA.

  • What type of abort?

    What's that "bx lr" doing inside your inline asm? That's absolutely forbidden. It would also be a good idea to add a "memory" clobber to both inline asm statements to ensure the compiler won't reorder memory accesses across them.

    If the memory is (inner) shareable it should be normal write-back (with cache enabled), if it is non-shareable it must be normal memory but afaik the cache policy shouldn't matter.

    Make sure that the address is 4-byte aligned to avoid an alignment exception.

  • Good points, thank you. Those inline assemblies were copied somewhere from the internet, as a "working example" - but they didn't seem to be just that :)

    However, I managed to overcome the problem with GCC __atomic_compare_exchange_n, that seems to use those instructions as a base, but adding some stuff. There is no need to add any assembler instructions.

    --Jussi

  • Yes, it's rare to need to write any assembly for this.

    Instead of using the gcc custom built-in, consider using C11 atomics or C++11 atomics, since these are portable across compilers and platforms. The gcc built-ins are intended primarlity for the implementation of standard atomics in the C <stdatomic.h> and C++ <atomic> headers.