1. 裸机编程任务栈设置
对于裸机编程,栈空间的大小分配也非常重要。局部变量,函数调用时的现场保护和返回地址,函数的形参,进入中断函数前和中断嵌套等都需要栈空间,栈空间定义小了会造成系统崩溃(一般情况下会跳转到一个异常中断内)。如图所示:
裸机的情况下,STM32F103工程中栈大小的配置文件
2. RTOS编程任务栈设置
在 RTOS 下,裸机编程里面的栈大小有了一个新的名字叫系统栈空间,而任务栈是不使用这里的空间的。一般系统栈空间在中断函数和中断嵌套时使用。
- 由于 Cortex-M3 和 M4 内核具有双堆栈指针,MSP 主堆栈指针和 PSP 进程堆栈指针,或者叫 PSP任务堆栈指针也是可以的。在 FreeRTOS 操作系统中,主堆栈指针 MSP 是给系统栈空间使用的,进程堆栈指针 PSP 是给任务栈使用的。 也就是说,在 FreeRTOS 任务中,所有栈空间的使用都是通过PSP 指针进行指向的。 一旦进入了中断函数以及可能发生的中断嵌套都是用的 MSP 指针。这个知识点要记住它,当前可以不知道这是为什么,但是一定要记住。
- 实际应用中系统栈空间分配多大,主要是看可能发生的中断嵌套层数,下面我们就按照最坏执行情况进行考虑,所有的寄存器都需要入栈,此时分为两种情况:
-
64 字节
对于 Cortex-M3 内核和未使用 FPU(浮点运算单元)功能的 Cortex-M4 内核在发生中断时需要将 16 个通用寄存器全部入栈,每个寄存器占用 4 个字节,也就是 16*4 = 64 字节的空间。可能发生几次中断嵌套就是要 64 乘以几即可。 当然,这种是最坏执行情况,也就是所有的寄存器都入栈。(注:任务执行的过程中发生中断的话,有 8 个寄存器是自动入栈的,这个栈是任务栈,进入中断以后其余寄存器入栈以及发生中断嵌套都是用的系统栈) -
200 字节
对于具有 FPU(浮点运算单元)功能的 Cortex-M4 内核,如果在任务中进行了浮点运算,那么在发生中断的时候除了 16 个通用寄存器需要入栈,还有 34 个浮点寄存器也是要入栈的,也就是(16+34)*4 = 200 字节的空间。当然,这种是最坏执行情况,也就是所有的寄存器都入栈。(注:任务执行的过程中发送中断的话,有 8 个通用寄存器和 18 个浮点寄存器是自动入栈的,这个栈是任务栈,进入中断以后其余通用寄存器和浮点寄存器入栈以及发生中断嵌套都是用的系统栈) - 通过以上的方法计算栈空间的话比较繁琐,而实际的任务栈空间大小分配,可以使用调试的方法,先给任务分配一个较大的栈空间,然后通过串口打印出任务剩余栈信息,根据这个信息来进行调整。