先来说堆栈是什么
堆(Heap):堆可以理解为一块内存,用户代码使用内存时从这块内存中分配,比如malloc函数。对于单片机来说一般情况下没有动态分配内存能力,大多数情况下不使用堆,有些操作系统有自己的内存分配函数。
栈(Stack):当func1调用func2时,处理器要保存现场(入栈),这里主要是func1的局部变量压入栈中,func2执行完毕后,从栈中恢复现场(出栈),func1继续执行。同样道理从用户程序到中断服务程序也有入栈出栈操作。有一点要注意,函数调用层次越深,局部变量越多(静态局部变量不算),使用的栈就越多,因此要合理编写代码。STM32是cortex-m3内核芯片,此内核是先进后出,满递减栈,先进后出好理解,所谓满递减栈就是栈指针指的位置总是满的,入栈时栈指针先减一个位置(对于cortex-m3来说是4个字节),然后放入数据。
综上所述,堆用的比较少,栈用的很多,但是基本上都是处理器自己处理,编程者无需过多干预。另外我们通常所说的“堆栈”这个词一般指的是栈。
cortex-m3有两个栈,也就是说有两个栈指针,可以通过配置寄存器设置使用哪个栈。栈虽然有两个,但是同一时间只能用一个。
第一个栈:MSP主栈
CONTROL[1]=0时,只使用MSP,这时候用户程序和异常(handler)共享同一个MSP栈。为了便于理解,说的直白一点,用户程序和中断程序都使用MSP,数据都保存在同一个栈中。
第二个栈:PSP进程栈
CONTROL[1]=1时,MSP和PSP都使用。用户程序使用PSP,中断程序使用MSP,数据保存在不同的两个栈中。比如说程序正在顺序执行,突然产生一个中断,处理器把现场保存在PSP栈中,然后进入中断服务程序,中断服务程序中使用MSP栈,退出中断时从PSP还原现场,返回用户程序。
有人说了,编程好几年了,没觉得有俩栈呀?一般我们裸跑程序(不跑操作系统)的情况下,默认使用的是MSP,因为Cortex-M3内核的芯片上电后,寄存器CONTROL[1]默认是0,使用MSP,异常和用户程序,都用这一个栈。PSP根本就没用到,那位又说了,PSP什么时候用?搞过实时操作系统的朋友一般都知道这个PSP。操作系统为每个任务或者说线程分配了各自的栈,栈各用各的,互不干扰,线程栈用PSP,内核用MSP,把栈区分开更保险。 |