0

I am using Particle.io firmware version 2.1.0, and I am attempting to make a function as a member of a class that will take one parameter, int waitForDuration and will loop until either the public member of the class has changed to value true or the duration has expired with the value remaining false. I have tried to write a function like this, which I will provide below, and this function works as expected for a few calls and eventually it will no longer wait for the boolean, instead return false immediately. If anyone can provide any insight on what is happening/why that would be appreciated. Thanks!

Files

MyClass.h

#ifndef MyClass_h
#define MyClass_h

namespace MyClass
{
    class MyClass
    {
        public:
            bool publicFlagMember;
            bool waitForFlag();
    }
}

MyClass.cpp

Function that I have previously tried

bool waitForFlag(uint16_t timeout)
{
    uint16_t timer = millis();
    while (millis() - timer <= timeout)
    {
        // call Particle.process() to ensure that when the variable changes we catch it
        delay(200);
        Particle.process();
        if (publicFlagMember)
        {
            return true;
        }
    }

    return false;
}
Ozzie
  • 139
  • 1
  • 3
  • 11
  • Is this multithreaded or how can `publicFlagMember` be changed while you are waiting in `waitForFlag`? If it is multithreaded, you need to synchronize your reads/writes to the variable. If it's a variable that is somehow changed in IRQ routines, you should make it `volatile`. Also, you have a declaration for a member function named `waitForFlag` and a definition of a free function named `waitForFlag`. These two are not connected. You could also simplify the wait loop: `uint16_t timer_end = millis() + timeout; while (millis() < timer_end) { ...` - You should probably use a wider type though – Ted Lyngmo Jul 06 '21 at 19:51
  • @TedLyngmo Yes, this program is multithreaded. While the `waitForFlag()` function is executing, the flag in question will be changed by another function in another thread. – Ozzie Jul 06 '21 at 21:25
  • Then you need to synchronize the access to the variable somehow. You could try to make it atomic, if your arduino library has support for atomics. Instead of `bool publicFlagMember;` you `#include ` and declare the variable as `std::atomic publicFlagMember;` – Ted Lyngmo Jul 06 '21 at 21:27
  • @TedLyngmo I should note something else that I have tried with the same amount of success, so failure is creating a `volatile static bool`. I will look into atomic tomorrow, however I don't believe the OS has support for `std` – Ozzie Jul 07 '21 at 04:55
  • What thread library do you use? – Ted Lyngmo Jul 07 '21 at 06:16
  • @TedLyngmo That ones a little tricky, I will link the docs discussing threads in the particle.io ecosystem https://docs.particle.io/cards/firmware/system-thread/system-threading-behavior/ – Ozzie Jul 07 '21 at 13:57
  • Ah, ok. You then need to read [ATOMIC_BLOCK()](https://docs.particle.io/cards/firmware/system-thread/atomic_block/) and [Synchronizing Access to Shared System Resources](https://docs.particle.io/cards/firmware/system-thread/synchronizing-access-to-shared-system-resources/) and possibly [Waiting for the system](https://docs.particle.io/cards/firmware/system-thread/waiting-for-the-system/) which seems to be one of particle.io's built-in condition waiting mechanisms. – Ted Lyngmo Jul 07 '21 at 14:33

0 Answers0