Atomic Operators - mhightower83/Arduino-ESP8266-misc GitHub Wiki

Atomic Operators on ESP8266

(this is kinda old - I have not retried with the newer compiler) I tried to use an std::atomic_exchange(&lock, 1) function. The sketch compiles; however, it cannot link because of an "undefined reference to __atomic_exchange_4". Apparently, there are no test-and-set instructions on the ESP8266. So far it looks like, for memory exchanges that need to be atomic, you will need to disable and restore interrupts around the sensitive area.

  • For multi-architecture Arduino platforms, this repo looks good. He creates an ATOMIC() macro similar to the ATOMIC_BLOCK() that is available for Arduino AVRs.
  • In the Arduino ESP8266 core the interrupts.h file has two class-based options for doing this:
    • InterruptsLock - Disables all interrupts through level 15.
      {
           InterruptLock lock;
           // Do sensitive stuff with interrupts locked out.
      }
      // Back to normal interrupt operations in background.
      
    • A macro AutoInterruptLock(level) that defines a class inline, then uses it to start the process.
      {
           AutoInterruptLock(3);  // Allows interrupt levels above 3
           // Do sensitive stuff with interrupts up to 3 locked out.
      }
      // Back to normal interrupt operations in background.
      
    • Something like this also seems to compile down nicely:
      int interlocked_exchange_int(volatile int *target, int value) {
          uint32_t ps = xt_rsil(15);
          int oldValue = *target;
          *target = value;
          xt_wsr_ps(ps);
          return oldValue;
      }