栈 - Stack
堆 - Heap
它们是完全不同的概念。
1.普通前后台系统
main函数的while(1)属于后台,isr属于前台。
在主循环中调用函数完成具体功能,发生中断,从主循环中切换到isr,处理完毕回到主循环。整个过程只有一个栈。我们不妨将它称之为Main Stack。
一般写函数,形参个数不超过4个,此时通过R0 ~ R3传递函数参数;如果形参超过4个,则使用栈传递参数。函数内部的临时变量,从栈中分配。
一段伪代码:
main.c
void test_func1(void)
{
char str[128]; /* 数组占用128字节,调用函数时从Stack中分配 */
char *ptr; /* 指针变量占用4字节,调用函数时从Stack中分配 */
ptr = (char *)malloc(256); /* 分配的256字节来源于 Heap */
....
free(ptr); /* 用完释放,Heap看起来没有变化*/
}
int main()
{
test_func1(); /* 函数调用前后,Stack看起来没有变化 */
}
2.RTOS
假设有2个线程。
系统启动,从启动代码中开始运行,直到进入到高优先级线程中,使用Main Stack。
进入高优先级线程,使用该线程的栈,我们称之为Process Stack,即你帖子中提到的256字节的Stack。在thread_entry中进行函数调用的开销,都在这256字节的栈中完成。
rt_thread_create( "a", thread_entry, RT_NULL,256,4 ,20);
由于有2个线程,所以RTOS下的Stack合计为:
Main Stack Size + Thread1 Process Stack Size + Thread2 Process Stack Size
Q:
如果是前者,那么即使线程体中用的堆栈大小超过256,也不会影响线程运行吧?
A:
线程中的栈是用来做现场保护的。线程中的堆和栈是两个不同的概念,你可看前文的伪代码中的注释。
如果线程中,函数调用深度较深,如
thread_entry
--> func1
--> func2
--> func3
--> func4
而每个函数中都用了128字节的临时变量,所需要的栈远超过了256字节,导致栈溢出,可能破坏了其他线程的栈,可能导致某些变量的值异常,线程大概率就死掉了,一定会影响线程运行。