我怎么知道我的记忆满了?

时间:2010-11-10 09:17:34

标签: c memory stack stack-overflow microcontroller

我正在为c中的Atmel XMEGA微控制器编写固件,我想我已经填满了4 KB的SRAM。据我所知,我只有静态/全局数据和本地堆栈变量(我在我的代码中使用malloc)。

我使用局部变量来缓冲一些像素数据。如果我将缓冲区增加到51字节,我的显示器显示奇怪的结果 - 一个6字节的缓冲区正常。这就是为什么我认为我的ram已满并且堆栈正在覆盖某些内容。

创建更多可用内存我的问题因为我可以将一些静态数据移动到闪存中,只在需要时加载它。困扰我的是我从未发现记忆已经满了的事实。

当内存被填满而不是让它覆盖其他一些数据时,是否可能以某种方式设法(例如通过重置微控制器)?

4 个答案:

答案 0 :(得分:3)

要准确预测你需要多少叠加是非常困难的(如果你打开正确的选项,一些工具链可以解决这个问题,但它只是一个粗略的指南)。

检查堆栈状态的常用方法是在启动时使用已知值完全填充它,尽可能多地运行代码,然后查看未覆盖的数量。

工具链的启动代码甚至可能有一个选项来为您填充堆栈。

不幸的是,尽管概念非常简单:用已知值填充堆栈,计算剩余值的数量,实现它的现实可能需要深入了解特定工具的方式(特别是启动代码和链接器)工作。

检查堆栈溢出是否导致问题的粗略方法是使所有本地阵列“静态”和/或大大增加堆栈的大小,然后查看是否有更好的工作。在小型嵌入式系统上,这些都很难做到。

答案 1 :(得分:1)

  

“它是否可能被设定(例如   通过重置微控制器)   记忆被填满而不是   让它覆盖其他一些数据?“

我想你现在有一个像(1)这样的内存映射。 当堆栈和/或可变空间增长很多时,它们会相互碰撞并相互覆盖(*)。

另一种可能性是像(2)那样的内存映射。 当堆栈或可变空间超过最大空间时,它们会命中未映射的地址空间(*)。 根据控制器(我不确定AVR系列),这会导致重置/陷阱或类似情况(=你想要的)。

  [not mapped addr space][   RAM  mapped  addr  space   ][not mapped addr space] 
(1)                      [variables --->  *   <--- stack] 
(2)                     *[ <--- stack   variables --->  ]* 

(如果使用更多变量/堆栈,则箭头表示生长方向)

当然最好事先确定RAM足够大。

答案 2 :(得分:1)

通常,链接器负责为代码,常量,静态数据,堆栈和堆分配内存。通常,您必须为链接器指定所需的堆栈大小(和可用内存),如果它不适合所有内容,则会标记错误。

另请注意,如果您正在处理多线程应用程序,那么每个线程都有自己的堆栈,并且这些堆栈经常在线程启动时从堆中分配。

除非您的处理器有一些硬件检查堆栈溢出(不太可能),否则您可以使用几个技巧来监控堆栈使用情况。

  • 使用已知的标记模式填充堆栈,并检查堆栈内存(由链接器分配)以确定标记保持未损坏的程度。
  • 在定时器中断(或类似)中比较主线程堆栈指针与堆栈的基础以检查溢出

这两种方法在调试中都很有用,但它们不能保证能够捕获所有问题,并且通常只会在堆栈已经损坏其他内容后标记问题...

答案 3 :(得分:0)

通常你的编程工具知道控制器的参数,所以如果你使用了更多的话就应该警告你(没有mallocs,在编译时就知道了。)

但是你应该小心使用pixeldata,因为大多数显示器都没有线性地址空间。

编辑:通常您可以手动指定堆栈大小。为静态变量保留足够的内存,并为堆栈保留其余内容。