Background / Foreground Re-entry Question

I am concerned about the timing of when the function in a particle.function(myFunc) call is called when an event is received from the cloud and the normal processing in the Photon during loop().

What would happen if Serial.print() is called in myFunc() due to an event posted from the cloud, while software in loop() was also writing to the USB port to log what it was doing at the same time.

What about the setting and testing of variables. If the same variable is used in myFunc and in loop(), should a CLI/SEI (turning interrupts on and off) be used before changing the variable to insure the process of checking and setting is an atomic function.

How have others gracefully coordinated between the background Function call and processing in loop().

Particle.function calls aren’t called as an interrupt. They’re actually called between calls to loop(), or in Particle.process(), or delay(), so they don’t generally cause synchronization issues. Also, that’s how they’re able to allocate memory and use things like String that can’t be called from an interrupt service routine.

This is true even when system thread is enabled:
Cloud functions registered with Particle.function() and event handlers registered with Particle.subscribe() continue to execute on the application thread in between calls to loop(), or when Particle.process() or delay() is called. A long running cloud function will block the application loop (since it is application code) but not the system code, so cloud connectivity is maintained.
https://docs.particle.io/reference/firmware/photon/#system-thread

2 Likes

To: rickkas7

So given what you are saying, I assume that Serial.println() is an atomic function that would run to completion if called from myFunc (from the cloud) or called during loop(). And therefore, if both were writing to the USB port 'simultaneously", we would just see lines of text intermingled from both sets of software. Is this correct?

So if the loop code was reporting the time every 500ms, and myFunc was called from the cloud every so often and wrote "Cloud call to myFunc’, we would see lines of cloud called reports intermingled between some of the time of day reports.

Correct, the lines of output would be intermixed in your scenario, but each line would be intact and readable.
Another way of phrasing this is that particle functions, subscription handlers and your loop code are cooperatively scheduled, and the swap between them can only happen when you return from loop(), call delay(), call Particle.process(), or exit from a function or subscription handler.

In order to protect “shared resources” against concurrent calls of different threads these macros were introduced
https://docs.particle.io/reference/firmware/photon/#single_threaded_block-
https://docs.particle.io/reference/firmware/photon/#atomic_block-
https://docs.particle.io/reference/firmware/photon/#synchronizing-access-to-shared-system-resources

@Scruff - good to keep the shared resource issue in mind. The documentation indicates the only existing shared resource currently is Serial and specifically getting serial input. Does this also apply for Serial1 or strictly for Serial.

Just to iterate and underline what @rickkas7 said, cloud functions run on the same thread as the application so there is no chance of a function interrupting some action performed by your application.

I just confirmed with Mat and it currently only applies to USB Serial, but other resources are on the list to be added (Serial1 is one of them).