For me it isn't the reason of my intermittent locking because all my threads include threads.yield() function. As said before the solution seem be to grow thread stack size.
It's easy to extand stack size for threads (Ex threads.addThread(thread_SendDatas,0,2048),but what about Loop() who are thread 0 if don't make mistakes ?
RAM in many embedded systems, including Teensy, is divided into three parts:
1. Static variables - fixed size at the start of RAM (may also place code here)
2. Heap - allocated with new() and malloc() starting at end of static and growing up
3. Main stack - starts at the end of memory and grows down.
During normal operation, the heap expands upward while the stack expands downward, unless they both collide and the system has problems.
TeensyThreads creates a seperate stack for every thread. That stack is placed in the heap and grows down, same as the main stack. Thus, every thread's stack grows until it crashes with the heap below it. By consuming heap, it leaves less RAM for the main stack. The main stack (stack of thread 0) is unbounded. It starts at the end of memory and grows until it collides.
Usually, there's plenty of RAM and nothing will crash. Most functions don't consume much stack. Stack is consumed a lot by recursion or by having large local variables. For example, the following code will take up 80K of RAM in the stack while it is running:
Code:
int longCalc() {
int data[20480];
dosomething(data);
}
When it finishes, the stack will return and the RAM will be "released".
The problem with these scenarios is that "collisions" are often undetectable. Memory will just overlap and two pieces of code will overwrite each other, causing numerous obscure bugs. TeensyThreads provides a `getStackRemaining()` method to detect when you are running out of memory. It also provides a "stack_overflow_isr()" function you can override to catch this problem. The main stack does not do this.
One way to get around this is for you to put a marker in memory and see if it gets clobbered.
Code:
extern unsigned long _estack;
#define STACK_SIZE 10240/sizeof(unsigned long) // 10KB of stack
uint32_t *memory = (uint32_t*) (&_estack - STACK_SIZE);
*memory = 0xFEFEFEFE;
Then periodically check `*memory`. If it changes, either the heap grew over this point, or the stack grew over it.
TeenyThreads assumes a 10KB main stack size. The function `getStackRemaining(0)` will return how close the main stack pointer is to reaching the limit. The size can be changed in line 183:
Code:
const int DEFAULT_STACK0_SIZE = 10240; // estimate for thread 0?