Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: ldrex, strex, gcc atomic operations

  1. #1
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679

    ldrex, strex, gcc atomic operations

    Hi..
    today, I had a little problem with a simple loop:

    while (playing>0){;}
    (playing is "int")

    Sometimes, the cpu "crashed" (i have no debugger) - it stopped working.
    The variable "playing" is written (and read at some places) in an interrupt.

    Edit: Deleted my wrong interrupt/ldrex/strex stuff.. leads to confusion :-)
    Last edited by Frank B; 12-24-2014 at 09:42 AM.

  2. #2
    Member
    Join Date
    Aug 2013
    Location
    Ohio
    Posts
    88
    Hello Frank,

    I believe there are two considerations at play here:

    1) The variable "playing" must be declared with the volatile keyword: If not, the compiler assumes that your code "owns" the variable so all references after the first will produce identical results. This lets the compiler optimize the loop into either not executing at all if (playing <= 0) or a "while(1)" loop if (playing > 0) when executing the statement the first time.
    2) Generally speaking, the Teensyduino loop() function (which I'm assuming is how your "background" process is organized) should be allowed to return occasionally to allow some basic serial and other maintenance functions to run. That may (or may not be) why your Teensy appears to lock up with the original code.

    The exclusive operations are useful in situations where more than one "processor" may try to access a memory location, serving as the low-level support of a semaphore. The Teensy has only one processor and a DMA controller, so using the exclusive operations are probably not what you're looking for here, as they don't add any capability that is not available using classical interrupt controls or the optimization-disabling use of "volatile".

    My best guess why your use of the atomic functions can prevent the crashing is that the atomic operations force the compiler out of its reduction-to-null optimization. You can test that by reverting to your original code but use the "volatile" keyword in declaring your loop variable.

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Hi Len, thank you for your answer!
    Yes, i really should have mentioned it.. sorry. "playing" was, and is volatile. This was the first thing i changed today.
    Last edited by Frank B; 12-23-2014 at 10:15 PM.

  4. #4
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    969
    Seems to me your implementing a spin lock which can also be implemented with GCC builtin's such as:

    Code:
    //-----------------------------------------------------------------------
    volatile unsigned int _LOCK = 0;
    
    
    inline uint32_t sys_acquire_lock( volatile unsigned int *lock ) {
        do { 
          yield();// write your own yield handler to do stuff.
       }
       while ( !__sync_bool_compare_and_swap( lock, 0, 1 ) );
        return *lock;
    }
    //-----------------------------------------------------------------------
    inline uint32_t sys_release_lock( volatile unsigned int *lock ) {
        asm volatile ( "" ::: "memory" );
        *lock = 0;
        return *lock;
    }
    I would suggest look at your disassembly to make sure the compiler is actually using ldrex/strex in your locking code, I know the above does. Actually you can just release the lock by writing 0 to your LOCK variable. One thing you need to look out for is when using spin locks with mutilple ISR's with different priority levels is you can dead lock your teensy, you need to implement ISR masking similar to SPI stuff paul did. I used this for a simple scheduler library I made based off the fibers library. Not perfect solution but it works for my application.

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Ahhhh....

    just looked... you're right, Len!
    I changed so much today... somehow i deleted the "volatile" again.

    It's time for some free days...

    No duff, much simpler.. :-(

  6. #6
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    969
    I guess, still going to have issues with ISR's at different priority levels!

  7. #7
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    969
    actually the dissassembly of __atomic_store_n doesn't use ldrex or strex:

    Code:
    volatile int playing = 0;
    void setup() {
      while (__atomic_load_n(&playing, __ATOMIC_SEQ_CST)>0) {;}
    }
    
    
    void loop() {
      
    }
    
    //--------------------------------------------------------------------------------------------------------
    Disassembly of section .text.setup:
    
    
    00000000 <setup>:
       0:    4a04          ldr    r2, [pc, #16]    ; (14 <setup+0x14>)
       2:    f3bf 8f5f     dmb    sy
       6:    6813          ldr    r3, [r2, #0]
       8:    2b00          cmp    r3, #0
       a:    f3bf 8f5f     dmb    sy
       e:    dcf8          bgt.n    2 <setup+0x2>
      10:    4770          bx    lr
      12:    bf00          nop
      14:    00000000     .word    0x00000000
    
    
    Disassembly of section .text.loop:
    
    
    00000000 <loop>:
       0:    4770          bx    lr

  8. #8
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    super. i read it somewhere. don't trust the internet :-)

    no, the different levels are very easy to handle. just simply ingore them.. and think of single interrupt and a main program instead. :-)
    This was the first obscure "crash" which I had with my current project. lol i know volatile since a long time and forgot it.. then i inserted it..and somehow removed it again..

    time for hollydays :-)
    Last edited by Frank B; 12-23-2014 at 11:16 PM.

  9. #9
    Member
    Join Date
    Aug 2013
    Location
    Ohio
    Posts
    88
    Hi Frank,

    Glad you've gotten over the hump. Have a nice relaxed holiday!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •