ZHCAD47 September   2023 UCD3138 , UCD3138064 , UCD3138064A , UCD3138128 , UCD3138128A , UCD3138A , UCD3138A64

 

  1.   1
  2.   摘要
  3.   商标
  4. 1引言
    1. 1.1 检查每个栈的大小
  5. 2检查是否发生溢出
  6. 3总结
  7. 4参考文献

检查是否发生溢出

栈是 RAM 的一部分,在 load.asm 中被完全初始化为零。若要检查每个栈的使用情况,一种选择是从栈位置读取,然后查看栈底部是否有全零空间。有必要在代码运行时检查栈,这可以通过适配器和嵌入在 UCD3xxx 器件 GUI 中的存储器 Peek/Poke 工具来完成。

连接适配器,启动 UCD3xxx 器件 GUI,转到 Debug > Memory Peek/Poke。

GUID-20230526-SS0I-FPPQ-TRWP-WFZD2RMN9ZGM-low.png图 2-1 存储器 Peek/Poke

以用户栈为例。读取存储器的地址 0x6a80e 至 0x6bb00,如下所示。它显示大约使用了 60 个字节,4754 个字节仍然可用。当然,这很难捕捉到最坏的情况,因为代码运行期间栈会不时发生变化。但是,通过检查栈的边距大小,我们应该可以获得一些线索,以了解是否可能发生溢出。

GUID-20230526-SS0I-ZXNP-VXQ7-ZMRLND42TXPD-low.png图 2-2 通过存储器 Peek/Poke 检测栈使用情况

另一种选择是在固件中添加测试代码,以持续检查栈的底部(或某些边距的底部附近)是否为非零。检测到非零后,它会显示发生溢出,切换 IO 进行报告。此选项的好处是,它会在代码运行期间持续进行检查。

以监控器栈为例,检测代码可能与以下代码类似,其中 stack_mon.ptr 最初是指向监控器栈底部的指针。它必须从底部开始。


                if (((Uint32)stack_mon.ptr == (Uint32)SUP_STACK_TOP) || (Uint32)(*(stack_mon.ptr) != 0))
                {
                    // reached top of stack so the stack is all zeros (so stack is empty), or else encountered the stack (as encountered a non-zero word)
                    stack_sup_headroom = (int32)stack_mon.ptr - (int32)SUP_STACK_BOT;
                    if (stack_sup_headroom < STACK_MON_HEADROOM_ALERT)
                    {
                        LoopMuxRegs.DTCIOCTRL.bit.DTC_B_GPIO_VAL = 1;
                    }
                }
                else
                {
                    // move onto the next address in the stack
                    stack_mon.ptr++;
                }