一、说在前面的话
双堆栈机制是 FreeRTOS 实现任务调度和中断处理的一个重要手段。
二、定义
在 FreeRTOS 中,用户堆栈和系统堆栈是两个不同的内存区域,分别用于不同的目的。以下是它们的详细解释:
1. 用户堆栈(Task Stack)
-
定义:用户堆栈是每个任务独立拥有的堆栈空间,用于存储任务运行时的上下文信息。
-
作用:
-
保存任务的局部变量、函数调用信息(返回地址、参数等)。
-
在任务切换时,保存任务的当前状态(如寄存器值、程序计数器等)。
-
-
特点:
-
每个任务都有自己的用户堆栈,大小可以独立配置。
-
用户堆栈的大小取决于任务的需求(如函数调用深度、局部变量大小等)。
-
任务运行时,所有的函数调用和局部变量都使用用户堆栈。
-
2. 系统堆栈(Interrupt Stack 或 Kernel Stack)
-
定义:系统堆栈是全局共享的堆栈空间,主要用于处理中断和异常。
-
作用:
-
当中断发生时,保存中断上下文(如寄存器值、程序计数器等)。
-
用于执行中断服务程序(ISR)时的函数调用和局部变量存储。
-
-
特点:
-
系统堆栈是全局唯一的,所有任务和中断共享同一个系统堆栈。
-
系统堆栈通常较小,因为中断服务程序应尽量简短。
-
系统堆栈的优先级高于用户堆栈,中断发生时,处理器会自动切换到系统堆栈。
-
4. 双堆栈的工作流程
-
任务运行时:
-
使用用户堆栈存储任务的局部变量和函数调用信息。
-
任务切换时,当前任务的用户堆栈会被保存,下一个任务的用户堆栈会被恢复。
-
-
中断发生时:
-
处理器自动切换到系统堆栈,保存中断上下文。
-
中断服务程序(ISR)使用系统堆栈运行。
-
中断结束后,恢复之前的用户堆栈,继续执行任务。
-
5. 双堆栈的优势
-
隔离性:用户堆栈和系统堆栈分离,避免任务和中断相互干扰。
-
可靠性:系统堆栈专用于中断处理,确保中断服务程序不会破坏任务的状态。
-
灵活性:每个任务可以独立配置用户堆栈大小,适应不同的需求。
三、示例:ARM Cortex-M 的双堆栈机制
1)任务运行时
-
处理器使用 PSP(用户堆栈指针)访问任务的用户堆栈。
-
用户堆栈存储任务的局部变量、函数调用信息等。
(2)中断发生时
-
处理器自动切换到 MSP(系统堆栈指针)。
-
系统堆栈保存中断上下文。
-
中断服务程序(ISR)使用系统堆栈运行。
(3)中断结束后
-
处理器恢复 PSP,继续执行任务。