我正在使用IAR Embedded Workbench IDE和TI CC2540蓝牙低功耗8051芯片进行一个C项目。我似乎得到吨的XData堆栈和Idata堆栈溢出,而工作的项目,它一直很难确定我溢出是从哪里来的。我正在与大量的字符串通过UART端口。我想知道是否有人有任何提示,如何确保我在分配内存后释放内存,并确保我停留在我的堆栈和堆的边界内。谢谢
lskq00tm1#
为了避免堆栈溢出,你应该避免以下情况:1)递归(在嵌入式系统中使用递归不是一个好主意)2)尽量避免动态分配。在大多数情况下,您并不需要动态分配。在汽车领域,有几条用于编程ECU的规则,称为MISRA规则,建议不要使用动态分配的内存和递归。IAR Embedded Workbench是少数几个支持MISRA C的IDE之一。尝试启用MISRA C选项(这可能表明您的问题所在)。了解如何完成here。
jobtbby32#
从this TI's forum开始,只是想了解一下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(XDATA内存)。CODE内存加上CONST内存的总和不得超过设备的最大闪存大小(128 KB或256 KB,取决于CC 2540/41的版本)。XDATA存储器的大小不得超过7936字节,因为CC 2540/41包含8 kB的SRAM(保留256字节)。在密切关注XDATA不超过~ 8 k的同时,您可能需要调整代码定义的缓冲区/大数组。最小的SimpleBLEPeripheral应用本身消耗接近6- 7 k的内存,除此之外,还有足够的空间为您的应用资源分配一些内存。[我知道,很晚才回答,但可能对其他读者有帮助]。
xienkqul3#
你可以在你的链接器配置文件(.icf)中改变栈和堆的大小。Project-〉Options-〉Linker-〉Config。可以在内置编辑器中做一些小的修改,但是它太可怜了,你应该只使用文本编辑器。您将看到类似以下内容的内容:
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};
我认为把HEAP的大小设置为零是可以的,这样所有的malloc调用在运行时都会失败,但是酷孩子们在嵌入式系统中并不使用动态内存。如何估计堆栈大小?EWB手册建议将以下内容添加到.icf中:
check that size(block CSTACK) >= maxstack("Program Entry") + totalstack("interrupt") + 100;
如果CSTACK太小(100只是一个模糊因子),这应该会抛出一个错误。在我的例子中,链接器只是抛出了错误“我无法计算出你的堆栈大小”。IAR的.icf格式让我想起了AppleScript(不是很好)。
zxlwwiss4#
我不知道这是否适用于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
然后在我的节点的选项中,在linker-〉advanced中,我们标记Enable stack usage analysis。在IDE选项中,我们选择“enable graphical stack”等。现在,在调试会话中,我们选择View-〉Stack,启用堆栈的图形表示。使用这种方法,您还可以转储整个RAM,并确定0xCDCD模式是否存在。另一种方法涉及到uC中的DWT OR MPU,以监视总线访问是否跨越边界并触发异常。通过这种方法,您可以准确地看到堆栈溢出时谁在做什么。同样,这是一种ARM定制方法,我不知道它是否适用于您的系统。K.R.公司
4条答案
按热度按时间lskq00tm1#
为了避免堆栈溢出,你应该避免以下情况:
1)递归(在嵌入式系统中使用递归不是一个好主意)
2)尽量避免动态分配。在大多数情况下,您并不需要动态分配。
在汽车领域,有几条用于编程ECU的规则,称为MISRA规则,建议不要使用动态分配的内存和递归。
IAR Embedded Workbench是少数几个支持MISRA C的IDE之一。尝试启用MISRA C选项(这可能表明您的问题所在)。了解如何完成here。
jobtbby32#
从this TI's forum开始,只是想了解一下TI的2540/1堆栈大小。
当您编译完项目后,您可以查看“.map”文件(输出文件夹)的底部。
例如,心率示例项目:
此信息非常有用,因为它告诉您代码空间的总量(代码存储器)和RAM(XDATA内存)。CODE内存加上CONST内存的总和不得超过设备的最大闪存大小(128 KB或256 KB,取决于CC 2540/41的版本)。XDATA存储器的大小不得超过7936字节,因为CC 2540/41包含8 kB的SRAM(保留256字节)。
在密切关注XDATA不超过~ 8 k的同时,您可能需要调整代码定义的缓冲区/大数组。最小的SimpleBLEPeripheral应用本身消耗接近6- 7 k的内存,除此之外,还有足够的空间为您的应用资源分配一些内存。
[我知道,很晚才回答,但可能对其他读者有帮助]。
xienkqul3#
你可以在你的链接器配置文件(.icf)中改变栈和堆的大小。Project-〉Options-〉Linker-〉Config。可以在内置编辑器中做一些小的修改,但是它太可怜了,你应该只使用文本编辑器。
您将看到类似以下内容的内容:
我认为把HEAP的大小设置为零是可以的,这样所有的malloc调用在运行时都会失败,但是酷孩子们在嵌入式系统中并不使用动态内存。
如何估计堆栈大小?EWB手册建议将以下内容添加到.icf中:
如果CSTACK太小(100只是一个模糊因子),这应该会抛出一个错误。在我的例子中,链接器只是抛出了错误“我无法计算出你的堆栈大小”。
IAR的.icf格式让我想起了AppleScript(不是很好)。
zxlwwiss4#
我不知道这是否适用于IAR的非ARM版本,我可以分享我们的方法:
在启动文件中,我们只使用IAR用来测量堆栈使用情况的模式来编辑RAM的初始化:
然后在我的节点的选项中,在linker-〉advanced中,我们标记Enable stack usage analysis。在IDE选项中,我们选择“enable graphical stack”等。
现在,在调试会话中,我们选择View-〉Stack,启用堆栈的图形表示。
使用这种方法,您还可以转储整个RAM,并确定0xCDCD模式是否存在。
另一种方法涉及到uC中的DWT OR MPU,以监视总线访问是否跨越边界并触发异常。通过这种方法,您可以准确地看到堆栈溢出时谁在做什么。
同样,这是一种ARM定制方法,我不知道它是否适用于您的系统。
K.R.公司