I have some issues with flashing a Xenon with SYSTEM_THREAD(ENABLED).
It is not possible to flash when using SYSTEM_THREAD(ENABLED).
Only after entering safe mode I am able to flash the Xenon correctly.
Is there any trick I can do to flash my Xenon without entering safe-mode?
EDIT: not only Xenon. on Photon the same issue.
Hum, on a Photon I’ve got the same behavior.
After some testing, I found the problem.
It makes sense where you start the thread function.
In my first example, I started the tread at the end of the main setup.
In that case, everything works ok, but only flashing did not work.
Now I start the tread direct after the declaration and not in the setup. That makes sense!
Now I can flash the device normally.
My new code:
#include "somelibrary"
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);
void threadFunction(void);
Thread thread("testThread", threadFunction); // <- HERE
void setup() {
// some setup stuff
// <- NOT HERE
Particle.connect();
}
void loop() {
// loop code here
}
void threadFunction(void) {
while(true) {
//some thread code here
os_thread_yield();
}
}
Maybe the issue was bigger than only flashing. I didn’t test any cloud function, but I wasn’t able to catch any system event with the System.on(all_events, handle_all_the_events); function.
In my opinion, this is kind of weird.
Maybe someone can explain this?
Your first example declared your Thread() as a local variable of the setup function. That means all storage for the Thread() instance was on the stack and corrupted as soon as you returned out of setup and did anything else. I’m honestly surprised you didn’t run into even more severe problems. Not worth much effort sorting out why OTA in particular failed. Maybe the system tries to check status on all threads when preparing for an OTA which references the corrupted memory and causes a fault?
Either way…
Starting your thread in global scope isn’t a great idea either. Global constructors happen in a non-deterministic order and before rest of the system initialization which can also cause all sorts of problems. Suggest either declaring a Thread pointer global and using new from setup (if you need a reference to your thread) or simply declaring it like before inside of setup() but adding the static keyword.