有几次,在将代码上传到 Arduino 后,串行监视器上出现了一些可疑的输出:比如空格的永久输出或突然切断的字符串或加扰的字符串。
因为在 Arduino IDE 中没有编译错误或警告,所以我认为 Arduino 坏了,但经过一些测试后,我发现 Arduino IDE 编译器并没有捕捉到所有类型的错误——尤其是在为数组结构分配循环中的变量时。这似乎在短时间内使 Arduino 崩溃。
如何发现 Arduino IDE 未显示的错误?
有几次,在将代码上传到 Arduino 后,串行监视器上出现了一些可疑的输出:比如空格的永久输出或突然切断的字符串或加扰的字符串。
因为在 Arduino IDE 中没有编译错误或警告,所以我认为 Arduino 坏了,但经过一些测试后,我发现 Arduino IDE 编译器并没有捕捉到所有类型的错误——尤其是在为数组结构分配循环中的变量时。这似乎在短时间内使 Arduino 崩溃。
如何发现 Arduino IDE 未显示的错误?
MemoryFree库可以帮助您发现内存使用的风险。
例子:
#include <MemoryFree.h>
// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)
// 14-bytes string
//char str[] = "Hello, world!";
void setup() {
Serial.begin(115200);
}
void loop() {
//Serial.println(str);
Serial.print("freeMemory()=");
Serial.println(freeMemory());
delay(1000);
}
我不确定 MemoryFree 是否考虑了堆栈指针。如果您的堆栈指针与您的堆指针冲突,您可能会遇到分段错误。
RAM 耗尽的最常见原因是使用 String 对象或使用大量常量字符数组(c 样式字符串)。
Forutantly IDE 1.0.4 包含对 malloc 的修复,该修复困扰了字符串对象很长时间。
减少常量字符串浪费的 RAM,例如:
Serial.print("Hello World"); // This consumes RAM!
您可以使用 F() 宏。此宏将强制字符数组留在 PROGMEM 中。使用数组时,只消耗一个字节的内存。
Serial.print(F("Hello World")); // Keeps the character-array in PROGMEM
请记住,存储在 PROGMEM 中的字符串在运行时不能更改。
就发现而言,没有调试器或内存控制器,您必须使用老式的检测技术来查找问题发生的位置。
看起来您在这里谈论的是运行时错误(内存泄漏/段错误类型)。
没有任何方法可以在已经编写的代码中发现此类错误(除非您非常仔细地梳理代码)。但是,在编写代码时很容易防止这些情况发生。在编写循环或递归调用时要非常小心;问问自己“这会失控吗?”。如果看起来这些是它“失控”的范围,那么编写代码来防止这种情况发生。
关于段错误——只需检查数组索引的边界值就可以了。如果您使用的是指针,那么请注意指针运算。