1、前言
- 要知道栈的概念,可以参考博客:《C语言与堆栈的理解》、《4种栈结构和对应的ARM指令后缀》
- 要知道CPU启动时如何设置栈:需要了解sp寄存器,这是栈寄存器
- RISC-V架构的中断入口和异常入口可以是同一个入口,也可以单独设置成不同的入口。也就是发生异常或者中断时,跳转的地址是否是同一个,本文是按照中断和异常的跳转地址不相同分析的
2、业务栈、异常栈、中断栈介绍
- 业务栈:运行业务代码时用到的栈。如果支持任务调度,不同任务的栈也是独立的
- 异常栈:当CORE进入异常时,跳转到异常处理代码时用到的栈
- 中断栈:当CORE接收到中断时,跳转到中断处理代码时用到的栈
3、设置栈空间
- 分配栈空间:参考博客《分配栈空间的三种方式(基于适配qemu的FreeRTOS分析)》
- 设置栈空间:参考博客《FreeRTOS的三处栈空间设置分析》
4、实现栈空间独立
- RTOS启动时:
- 当发生异常时:
- 跳转到异常处理入口,先将异常现场保存到业务栈空间中,然后再设置sp指向异常栈空间
- 异常处理完成,将sp指向业务栈空间,从业务栈空间中恢复现场,继续执行业务
- 当发生中断时:
- 跳转到中断处理入口,先将中断现场保存到业务栈空间中,然后再设置sp指向中断栈空间
- 中断处理完成,将sp指向业务栈空间,从业务栈空间中恢复现场,继续执行业务
5、栈独立设置的优劣势
- 优势:
- 业务、中断、异常是CPU运行中三种不同的状态,独立设置可以保证不同状态的栈直接互相不会影响
- 比如当业务运行时发生 栈空间溢出,此时溢出的是业务栈,当跳转到异常入口时,切换到异常栈空间,异常处理程序还是可以正常运行的
- 不同状态之间的栈信息独立,互相不可见,可以更安全
- 劣势:
- 要为每个状态都分配栈空间,状态切换要更麻烦,因为要切换栈空间
- 栈空间的利用率不高
- 中断和异常在程序运行的时间中占比是比较小的,分配给中断和异常的栈空间利用率不高