C语言 Arduino纳米:内存稳定性问题

mm9b1k5b  于 2023-01-25  发布在  其他
关注(0)|答案(5)|浏览(383)

目前,我正在使用Arduino nano。当我在Arduino IDE中编译我的c代码时,我得到了以下错误。

程序上传成功,工作正常,那么这个错误背后的原因是什么?它真的会影响arduino nano的性能吗?

wqsoz72f

wqsoz72f1#

出现此警告是因为编译器不知道程序应该分配多少动态内存。请查看程序的动态分配、局部变量分配...
真的会影响arduino nano的性能吗?
就像它说的 “稳定性问题可能会发生”。我过去确实面临过这个问题,项目有时会滞后运行。

bt1cpqcv

bt1cpqcv2#

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

调用此函数,例如

Serial.println(freeRam());

在您的函数的最深层次或您想要的任何地方。
不要使用malloc()或c++ new,以避免“稳定性问题”,因为在动态内存分配中没有异常处理或其他错误检查。

vddsk6oq

vddsk6oq3#

真的会影响arduino nano的性能吗?
我也得到了同样的错误,而编译这是一个警告正如你说你上传成功,如果上传成功,那么就没有性能问题。如果你想清除这个错误,你需要**减少一些内存使用你的代码,**只是优化你的代码,尽可能多地使用局部变量。此外,如果你有常数,使用#define代替,将重复的调用分组到函数中。

91zkwejq

91zkwejq4#

如前所述,这只是一个警告,但根据实际内存使用情况,您可能会得到不稳定的行为。
我最近做了一个小项目(https://releasetheinnergeek.wordpress.com/2018/05/16/minimalist-lidar/),根据剩余的动态内存,观察到不同的行为,例如:伺服系统不工作,屏幕显示不正确和/或激光读数不准确。
从使用70%开始你会得到警告。实际的行为取决于。

rdrgkggo

rdrgkggo5#

微控制器上没有所谓的“性能”:它总是以系统时钟频率执行闪存汇编指令。它以如下方式发生:第一个字节(总是指令)被移位到CPU并作为指令处理;下一个字节可以是数据字节或下一个指令字节(取决于第一条指令),等等。因此,命令字节或数据字节没有区别或特殊的“标记”。当正确编译和闪存程序工作时,CPU总是将所有命令字节解释为命令,将所有数据字节解释为数据,因为它们都以正确的顺序出现。
将要移位的当前程序字节的地址存储在程序计数器寄存器中,该寄存器的值随每个执行的指令递增1。
现在,让我们看看avr-gcc编译器使用的AVR微控制器的标准内存Map:

有数据放在.data变量和.bss变量部分,这是在编译程序时已知的。它在Arduino IDE日志中被称为“全局变量”。当您的程序动态分配内存时,它被放在堆部分,而函数使用的局部变量和一些寄存器的值则放在栈段。只有当堆段和栈段彼此不冲突时,一切才能正常工作(即是否有足够的可用RAM)。
如果没有剩余的可用RAM,会出现什么问题?
仅举一个假设空闲内存已用完的示例:
1.程序执行某个函数。这是使用jmp指令完成的。
1.在跳转到函数的程序地址之前,程序计数器(PC)的当前值存储在堆栈中。当函数完成执行时,堆栈中的PC值用于恢复当前运行程序的位置,并从函数调用之后的点继续执行。
1.函数在堆段中分配了一些数据,但没有剩余的可用RAM,因此数据重写了以前存储的程序计数器值。
1.函数以ret指令结束。程序计数器的值被恢复,但此时它指向错误的位置,这可能不仅仅是错误的指令,甚至是错误的数据。
1.此时,CPU将数据解释为命令,随后的行为变得不可预测。
低可用内存问题本身并不是一个错误,但可能是不可预测的行为和稳定性问题的原因。只要遵循其他评论的建议,以防止此类问题。
事实上,如果一切都做对了,即使只有很少的可用RAM,程序也可以保持稳定。

相关问题