HRTOS · Stack Management MEMORY / STACK

栈管理
Stack Management

栈空间承载函数调用、局部数据和部分执行现场,其使用边界直接关系到系统可靠性。 本页从 8051 SP 寄存器、任务栈布局、运行时边界检查与异常处理 出发, 说明软件检测能够覆盖哪些风险,以及它无法替代哪些硬件保护能力。

SP 寄存器 任务栈 中断现场 边界检查 溢出处理
返回内存管理 从栈布局到运行时风险控制
01

栈模型与 8051 的约束

栈不仅是任务资源,也会受到调用深度与中断执行的共同影响。

在经典 8051 架构中,SP(Stack Pointer)用于指示当前栈顶位置。 典型 PUSH 操作会先递增 SP,再将数据写入新栈顶位置; 因此,分析栈使用情况时,必须结合具体指令行为、内存区域和初始 SP 值。

HRTOS 的任务栈、内核使用栈和中断执行期间的栈需求,应根据实际内存布局分别分析。 如果多个执行路径共享某段栈空间,或中断期间仍会继续压栈,就必须把这些路径的叠加使用量纳入预算。

栈空间示意图 · 逻辑布局,不代表实际地址比例
已规划的栈空间 由系统配置与内存布局决定
栈顶随压栈操作变化
当前使用区域 函数调用、现场保存等
边界风险区域 具体位置须按真实边界定义判断
注意:示意图不代表所有栈都采用相同的地址方向或边界定义。 应以目标芯片、HRTOS 的栈分配实现和实际检查代码为准。

关键概念: 栈容量规划、栈使用量监测和栈越界拦截是三种不同能力。 即使系统能检查某个时刻的 SP,也不代表它能够发现所有已经发生的越界写入。

02

SP 边界检测

检查条件必须与栈边界的定义和实际栈增长方式一致。

软件可以在任务切换、进入内核或其他指定检查点读取 SP, 并将其与该执行路径对应的有效栈范围进行比较。 但检查是否存在、在哪些路径执行,以及比较的是哪个栈区间, 都必须由实际实现确认。

Stack Boundary Check · 检查原理
读取当前 SP
确定需要检查的栈区域
依据该区域的边界定义执行检查

若检测到栈异常:
    调用 HRTOS 栈溢出处理路径

经典 8051 的栈通常随压栈操作向高地址方向增长, 但边界比较条件必须与实际栈区间、初始 SP、检查时机和具体实现一致。 HRTOS 的具体检查逻辑应以其真实实现为准,不宜用未经核实的变量名和比较式代替。

实时性说明: 边界检查可能带来额外指令开销。 其时间成本应通过目标编译器生成的汇编或实测确认, 不宜在没有测量的情况下断言“完全不影响实时性”。

03

栈溢出与异常处理

通过溢出处理入口与可注册回调,建立异常发生后的处理路径。

HRTOS 提供 os_slab_overflow() 栈溢出处理函数、 os_slab_overflow_register() 回调注册接口,以及 g_slab_overflow_hook 回调函数指针。 应用可以通过注册回调接入自定义处理逻辑,使异常处理与具体应用需求相结合。

HRTOS API · 栈溢出处理
void (*g_slab_overflow_hook)(void);

void os_slab_overflow(void)
{
    if (g_slab_overflow_hook)
    {
        g_slab_overflow_hook();
    }
    else
    {
        while (1);
    }
}

void os_slab_overflow_register(void (*hook)(void));

当回调已经注册时,os_slab_overflow() 会调用 g_slab_overflow_hook 指向的处理函数; 未注册回调时,上述实现进入循环停机路径。 os_slab_overflow_register() 用于注册处理回调。

自定义故障处理

可以结合应用需求设计故障记录、状态标记或其他处理动作, 并评估这些操作在异常发生时是否仍然安全。

未注册回调时的行为

当前展示的实现采用循环停机路径。 这可以避免在该路径中继续执行普通业务流程, 但不等同于自动复位或硬件级故障隔离。

异常处理注意事项: 栈溢出可能已经破坏当前执行环境。 回调逻辑应尽量精简,避免依赖可能受损的栈、复杂函数调用或未经保护的共享状态。 具体回调执行上下文与可调用范围,应结合 HRTOS 的实际调用路径设计。

04

栈容量预算与高水位

把任务调用、中断使用和系统保留空间放在同一张资源账本中分析。

栈需求不仅来自任务代码本身。函数调用层数、局部变量、编译器生成的临时数据、 中断现场保存以及嵌套执行路径,都可能影响峰值使用量。 对 8051 这类资源受限平台,容量预算应结合实际编译结果和执行路径进行。

Stack Budget · 分析框架
栈需求分析应覆盖:

1. 任务调用路径的最大使用量
2. 内核调用与上下文切换的额外使用量
3. 中断入口、现场保存及嵌套中断
4. 编译器生成代码带来的栈使用
5. 必要的余量与异常处理路径

高水位(High-Water Mark)通常通过预填充标记并在运行后检查残留区域, 或通过其他监测方法估算历史最大栈使用量。 这种方法能否用于某个 HRTOS 栈区,取决于该区域是否可安全初始化和扫描, 以及监测代码是否覆盖全部相关执行路径。

实践建议: 结合静态汇编分析、典型负载测试和压力测试评估栈使用量。 单次运行未触发溢出,并不能证明所有输入和中断组合下都不会发生栈越界。

05

中断与多层执行路径

栈分析必须覆盖任务执行期间发生的异步路径。

在 8051 系统中,中断响应可能触发额外的现场保存和函数调用。 如果高优先级中断能够打断较低优先级中断,或者中断处理程序调用了内核 API, 就需要按实际控制流分析这些路径的叠加使用量。

01
任务正常执行 评估函数调用、局部数据及任务本身的栈需求。
02
中断入口与现场保存 根据实际汇编和编译结果核算额外压栈量。
03
中断内调用与嵌套 检查是否存在嵌套、内核调用或其他额外执行层。
04
恢复现场并返回 核对所有返回路径是否正确恢复执行状态。

不要混用栈区: 任务栈、内核栈和中断栈是否独立、是否共享,以及各自的实际容量, 应以当前 HRTOS 版本的内存布局和汇编实现为准。

06

栈安全与任务隔离的边界

边界检查可以发现部分异常,但不能自动建立硬件级访问隔离。

对任务栈进行独立分配和边界检查,有助于组织资源并发现部分栈使用异常。 但在没有 MPU/MMU 的系统中,如果任务代码可以直接读写某段 RAM, 仅仅维护栈边界信息并不会自动禁止这类访问。

栈边界检查

在实际执行检查的路径上识别满足检测条件的异常 SP 状态。

内存访问隔离

需要额外的访问控制、受限接口或其他明确机制,不能由 SP 检查单独实现。

越界写入检测

SP 合法并不代表此前没有发生非法写入;还需确认是否存在相应检测机制。

栈使用量监测

高水位记录反映已观测到的使用情况,不等于对未来峰值的形式化保证。

准确的安全表述: 软件级栈管理可以通过资源规划、边界检查和错误处理提升可诊断性与可靠性; 其覆盖范围取决于实现,不能等同于硬件内存保护或绝对的任务隔离。

07

实现核对与验证清单

把文档中的每项能力映射到实际代码和可复现测试。

A
核对栈区域定义 确认任务栈、系统栈、中断栈的起止位置和容量。
B
核对 SP 检查代码 确认比较方向、边界包含规则、检查时机及异常分支。
C
验证栈溢出处理路径 验证 os_slab_overflow() 的调用条件、回调注册与执行行为, 并确认未注册回调时的处理路径。
D
验证边界与嵌套场景 测试临界栈深度、任务切换、中断嵌套和异常返回路径。

完成核对后,可以将确实存在的机制、对应配置和测试结论写入正式文档, 并明确区分静态分析结果、压力测试结果与理论保证。