如何在IAR Workbench中调试C中的堆栈溢出
我正在使用IAR Embedded Workbench IDE和TI CC2540蓝牙低能8051芯片进行一个C项目 在这个项目中,我似乎遇到了大量的扩展数据堆栈和Idata堆栈溢出,我很难确定溢出的来源。我正在通过UART端口处理大量字符串 我想知道是否有人知道如何确保我在分配内存后释放内存,并确保我保持在堆栈和堆的边界内如何在IAR Workbench中调试C中的堆栈溢出,c,debugging,memory-leaks,stack-overflow,iar,C,Debugging,Memory Leaks,Stack Overflow,Iar,我正在使用IAR Embedded Workbench IDE和TI CC2540蓝牙低能8051芯片进行一个C项目 在这个项目中,我似乎遇到了大量的扩展数据堆栈和Idata堆栈溢出,我很难确定溢出的来源。我正在通过UART端口处理大量字符串 我想知道是否有人知道如何确保我在分配内存后释放内存,并确保我保持在堆栈和堆的边界内 谢谢为了避免堆栈溢出,您应该避免以下情况: 1) 递归(在嵌入式系统中使用递归不是一个好主意) 2) 尽量避免动态分配。在大多数情况下,你不需要它 在汽车中,有几种编程EC
谢谢为了避免堆栈溢出,您应该避免以下情况: 1) 递归(在嵌入式系统中使用递归不是一个好主意) 2) 尽量避免动态分配。在大多数情况下,你不需要它 在汽车中,有几种编程ECU的规则称为MISRA规则,建议不要使用动态分配的内存和递归。这里有一个
IAR Embedded Workbench是少数几个支持MISRA C的IDE之一。请尝试启用MISRA C选项(这可能表明问题所在)。查看它是如何完成的。您可以更改链接器配置(.icf)文件中的堆栈和堆大小。项目->选项->链接器->配置。可以在内置编辑器中进行细微更改,但这太可怜了,您应该只使用文本编辑器 在这里,您将看到如下内容:
define block CSTACK with alignment = 8, size = 0x0400 {};
define block HEAP with alignment = 8, size = 0x0200 {};
place in MY_RAM_region {block CSTACK, block HEAP};
您可以根据需要进行更改。我认为可以将堆大小设置为零。然后,所有malloc调用都会在运行时失败,但酷酷的孩子们无论如何都不会在嵌入式系统中使用动态内存
如何估计堆栈大小?EWB手册建议将此项添加到.icf中:
check that size(block CSTACK) >=
maxstack("Program Entry") + totalstack("interrupt") + 100;
如果CSTACK太小(100只是一个伪造的因子),那么这会抛出一个错误。在我的例子中,链接器只是抛出了一个错误“我不能计算出你的堆栈大小”
IAR的.icf格式让我想起了AppleScript(不是一个好的方式)。来自,只是想对TI的2540/1堆栈大小有所了解
编译完项目后,可以查看“.map”文件(输出文件夹)的底部
例如,心率示例项目:
108 019 bytes of CODE memory
26 bytes of DATA memory (+ 73 absolute )
6 089 bytes of XDATA memory
192 bytes of IDATA memory
8 bits of BIT memory
702 bytes of CONST memory
此信息非常有用,因为它告诉您项目正在使用的代码空间(代码内存)和RAM(扩展数据内存)的总量。代码内存加常量内存之和不得超过设备的最大闪存大小(128KB或256KB,取决于CC2540/41的版本)。扩展数据内存的大小不得超过7936字节,因为CC2540/41包含8kB的SRAM(保留256字节)
在密切关注扩展数据不超过~8k的同时,您可能需要调整代码中定义的缓冲区/大数组。最小的SimpleBelipheral应用程序本身消耗了近6-7k的内存,在这些内存之上,刚好有足够的空间为您的应用程序资源分配一些内存
[我知道,回答得很晚,但可能会对其他读者有所帮助]。我不知道对于IAR的非arm版来说,这是否有效,我可以分享我们的方法: 在启动文件中,我们仅使用IAR用于测量堆栈使用情况的模式编辑RAM的初始化:
LDR R1, =__RAM_START
LDR R2, =__RAM_END
SUBS R2, R2, R1
SUBS R2, #1
BLE .LC5
MOVS R0, #0xCDCDCDCD ;; <- LOOK HERE!
MOVS R3, #4
.LC4:
STR R0, [R1]
ADD R1, R1, R3
SUBS R2, #4
BGE .LC4
LDR R1,=\u内存\u启动
LDR R2,=\uuu RAM\uu结束
潜艇R2,R2,R1
潜艇R2#1
立法会五题
MOVS R0,#0xcdcd;;高级我们标记启用堆栈使用分析。
在IDE选项中,我们选择“启用图形堆栈”等
现在,在调试会话中,我们选择View->stack启用堆栈的图形表示
使用这种方法,您还可以转储整个RAM,并确定0xCDCD模式是否保留在哪里
另一种方法涉及到我们uC中的DWT或MPU,以监视跨越边界的总线访问并触发异常。通过这种方法,您可以确切地看到堆栈溢出时谁在做什么
同样,这是一种ARM定制的方法,我不知道它是否能在您的系统中工作
K.R.了解堆栈大小,检查代码以查看函数中是否使用了可能导致堆栈溢出的非静态大型数组或结构。是否使用堆栈视图监视堆栈使用情况?它将告诉您堆栈上有哪些项,以及它的完整程度。因此,现在,我有一个大型结构,我可以根据需要动态alloc和dealloc,并作为指针传递。我从来没有一次创建多个这样的结构。该结构还包含一个指向字符串的指针,该字符串也是alloc和dealloc。静态创建此结构与不创建此结构有区别吗?我不明白你怎么能有一个这个结构的静态声明,并通过引用传递它。我同意你关于动态分配的观点。我删除了所有动态分配数组的实例,这些问题似乎已经最小化了位。您还可以尝试从链接器修改堆栈段大小。搜索链接器文件并修改堆栈_段的长度(根据我的记忆)。这样,您可能就不会再有堆栈溢出问题了。