2

我正在使用 IAR Embedded Workbench IDE 和 TI CC2540 蓝牙低功耗 8051 芯片进行 C 项目。

在处理项目时,我似乎遇到了大量的 XData 堆栈和 Idata 堆栈溢出,而且我很难确定溢出的来源。我正在通过 UART 端口处理大量字符串。

我想知道是否有人对如何确保在分配内存后释放内存并确保我留在堆栈和堆的边界内有任何提示。

谢谢

4

4 回答 4

4

好吧,为了避免堆栈溢出,您应该避免以下事情:

1)递归(在嵌入式系统中使用递归不是一个好主意)

2)尽量避免动态分配。在大多数情况下,您不需要它。

在汽车中,有几条用于对 ECU 进行编程的规则称为 MISRA 规则,这些规则建议不要使用动态分配的内存和递归。这是一个链接

IAR Embedded Workbench 是少数支持 MISRA C 的 IDE 之一。尝试启用 MISRA C 选项(这可能表明您的问题所在)。看看它是如何在这里完成的。

于 2012-11-20T03:18:51.643 回答
4

这个 TI 的论坛中,只是试图阐明 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

此信息很有用,因为它告诉项目正在使用的代码空间(CODE 内存)和 RAM(XDATA 内存)的总量。CODE 内存加上 CONST 内存的总和不得超过器件的最大闪存大小(128KB 或 256KB,取决于 CC2540/41 的版本)。XDATA 存储器的大小不得超过 7936 字节,因为 CC2540/41 包含 8kB 的 SRAM(保留 256 字节)。

在密切关注 XDATA 不超过 ~8k 的同时,您可能需要调整定义代码的缓冲区/大数组。最小的 SimpleBLEPeripheral 应用程序本身消耗接近 6-7k 的内存,除此之外,还有足够的空间为您的应用程序资源分配一些内存。

[我知道,答案很晚,但可能会帮助其他读者]。

于 2015-11-16T19:55:38.773 回答
0

您可以在链接器配置 (.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};

您可以根据需要进行更改。我认为可以将 HEAP 大小设置为零。然后所有 malloc 调用将在运行时失败,但酷孩子无论如何都不会在嵌入式系统中使用动态内存。

如何估计堆栈大小?EWB 手册建议将此添加到您的 .icf 中:

check that size(block CSTACK) >= 
      maxstack("Program Entry") + totalstack("interrupt") + 100;

如果 CSTACK 太小,这假设会引发错误(100 只是一个捏造因素。)在我的情况下,链接器只是抛出错误“我无法计算出你的堆栈大小”。

IAR 的 .icf 格式让我想起了 AppleScript(不是很好)。

于 2013-11-20T15:29:36.703 回答
0

我不知道对于 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

然后在我的节点的选项中,在链接器->高级中,我们标记启用堆栈使用分析。在 IDE 选项中,我们选择“启用图形堆栈”等。

现在,在调试会话中,我们选择 View-> Stack 启用堆栈的图形表示。

使用这种方法,您还可以转储整个 RAM 并找出 0xCDCD 模式的位置和位置。

另一种方法涉及我们的 uC 中的 DWT 或 MPU,以监视总线访问跨越边界并触发异常。使用这种方法,您可以准确地看到堆栈溢出时谁在做什么。

同样,这是一种为 ARM 量身定制的方法,我不知道这是否适用于您的系统。

韩国

于 2021-02-24T14:06:55.477 回答