7 Replies Latest reply on Nov 22, 2013 2:47 AM by bob.marlowe

    Atomic Operations

              Hello. I have two lines of code, one is to read a variable and the other is to reset it to zero. The problem is that the variable is only updated by interrupt, and I do not want to have an interrupt between these two lines. However, I do not want to miss an interrupt also, so disabling interrupts does not work for me. I figured out it should be done via atomic operations, but I couldn’t figured how or find an example. Could you guide me to do it, please.   
        • 1. Re: Atomic Operations

          One possibility, set a flag in main() when you want to execute the two lines of code, and if


          ISR fires and it finds the main() flag set, it sets another flag, saves value in a temp register,


          exits. When 2 lines finish then test for flag from ISR, and update variable if set and clear ISR






          Or look at disabling the interrupt, but leaving it pending, and re-enabling after two lines of code


          have executed. Take a look at interrupt controller in TRM manual for further info.




          Regards, Dana.

          • 2. Re: Atomic Operations
                    Hi frturan   
            I didn't understand what you want to do clearly.   
            and what is your ploblem was.   
            Disabling the global interrupt doesn't work only for you? that is odd   
            What is atomic operations?   
            Is that like a kind of test-and-set operation on assembler language?   
            You would be better write your code here.   
            • 3. Re: Atomic Operations

              ATOMIC operation in computing


              " There isn't any intermediate state that's visible before it completes.
              So if your CPU gets interrupted, or if another task(in multitasking system)
              is accessing the same memory, it doesn't affect the result, and these
              other operations will observe it as either completed or not started."


              In your case.


              I think what you should do is


              1. Ensuring there is no interrupt when you are reading/writing/updating that variable.


              2.  The function needs to disable interrupt while reading the variable and set a flag to indicate that
               it was read. enable interrupt after reading the value.
               The ISR would disable interrupts that would access that variable first, then read and clear the flag
                and based on the flag, perform the correct operation of the variable.

              • 4. Re: Atomic Operations

                Exactly for this purpose there are CyEnterCriticalSection() and CyExitCriticalSection() are for. Have a look into the "System Reference Guide" (Creator 3.0 -> Help -> System Reference).


                It does not make the instructions in between atomic, but it temporarily disables all interrupts for an area of code and safely re-enables it.


                Additionally consider to declare those variables that are changed from an interrupt handler as "voilatile" which will prevent errors coming from the excessive (but very good) optimization step in GCC.





                • 5. Re: Atomic Operations

                  Some more explanation:


                  You will not "miss" any interrupt when disabling interrupts, you just will delay its handling for some CPU-instructions. The PSoC4-internal Interrupt Controller Unit (ICU) will remember any interrupt occuring during a disabled time. When enabled back again the interrupt will fire after execution of the next instruction. Only when an interrupt is applied twice while disabled there is the chance that the second one is missed.





                  • 6. Re: Atomic Operations
                            Thank you for all your responses. Expecially, Bob Marlowe. I was thinking disabling interrupts will make me lose one, if occurs when dissabled. So it is a little bit interesting for me. Also I found CyEnterCriticalSection() in System Reference Guide, but I was stuck on using __ATOMIC_ACQUIRE; and __ATOMIC_RELEASE; type commands. Cretor comprises those commands (I think thanks to GCC); however, I could not found how to use them. Still your responses are so beneficial for me, and I think I will be able to. Thank you very much.   
                    • 7. Re: Atomic Operations

                      Your  __ATOMIC... operations are ment to work on threads sharing the same memory. Since threading needs an operating system that really supports threads and your PSoC4 doesn't have got one this are the wrong functions. These just prevent task-switching while the shared memory is accessed.