部件号:TMS320F2.8069万M
您好,
有时,当我使用过多的printf指令时,尝试运行我的代码(从RAM)会导致ISR或调试器在不属于任何源文件的内存位置中停止(甚至在到达起始符号之前)。 我认为这可能是由于超出堆栈范围造成的-事实上,增加堆栈大小通常会有所帮助。 但是,检测堆栈溢出的方法在此处不会发现任何错误!
1) 首先,当出现问题时,我在内存浏览器中找到stack_end大小,但仍有大量可用空间(链接程序文件中填充了0xDEAD)。 通常整个.stack部分似乎未被触及。
这是否意味着我可以确定堆栈没有损坏?
2) 接下来,我决定实施联机堆栈溢出检测(spra820)文档中描述的方法。 我实施了模范源代码,以便不返回任何错误,然后添加了尽可能简单的中断例程:
extern interrupt void Stackmonitor_ovfISR(void){
ASM(" ESTOP0");
}
...我在 HAL_initIntVectorTable()函数中链接到PIE:
PIE->RTOSINT =&Stackmonitor_ovfISR;
有趣的是,在实现此功能后,问题发生了变化:调试器在启动符号处正确停止,并且执行容易受到攻击的代码。 但是,它会在代码的其他部分停止(在正常执行几秒钟后),并显示“No source available for "0x3ff4fa"”(没有可用的源代码)。 我评论说我的更改试图再次唤起最初的情况,但这一次代码运行正常-直到代码开始反复重新启动。
这种行为可能是什么原因造成的? 增加堆大小不会更改任何内容,但增加堆栈可以使程序正常运行。
3) 为确保中断正确触发,我重新设置了堆栈大小,尝试强制执行其溢出。 但是,使用低于默认值0x1000的任何值都会导致以下问题:调试器甚至不能正常启动,“暂停”按钮变灰,大多数视图保持空白(寄存器,内存浏览器等)。
如何测试此功能以确保中断将触发以保存堆栈?
4) 我还有一个奖励问题。 在内存浏览器中,我可以看到两个现有符号:"_stack"和"_stack_end"。 但我无法在项目中的任何位置找到它们(绝对不在链接程序文件中)! 它们仅存在于地图文件中的"全局数据符号"(双下划线)下。
它们的定义在哪里?
5) 一些附加信息:
-我正在根据其中一个motorWare实验室示例开发代码,目前仅为RAM版本。
-我正在使用的栈大小为0x1000,堆大小为0x400。 尝试通过更改我的代码(使用更少的printf)来解决问题 ,而不是在每次出现堆栈时盲目增加堆栈。
-我使用的命令链接器文件附加在此处(我已 定义stack_end_X以将其与现有 stack_end区分开来): https://ufile.io/kl6g5