繁体   English   中英

由于Arduino上的指针导致无限循环

[英]Infinite loop due to Pointers on Arduino Due

我以Dan Royer的代码为基础在Arduino Mega 2560上实现了一个缓冲区。 代码在Mega上运行得非常好,但是我想使用Arduino Due(使用ARM而不是标准Atmel微处理器)的增强功能和强大功能。

在Due上,由于在到达缓冲区末端时不退出缓冲区内容,因此在处理缓冲区内容时,我总是陷入无限循环。 有谁知道为什么会这样? 您对如何防止这种情况有想法吗?

给出的命令将是GCode,例如:“ G01 X20.5 Y30;”。

这是缓冲区填充的方式:

char buffer[MAX_BUF];  // where we store the message until we get a ';'
int sofar;  // how much is in the buffer

while(Serial.available() > 0) {  // if something is available
  char c=Serial.read();  // get it
  if(sofar<MAX_BUF-1) buffer[sofar++]=c;  // store it
  if(c==';') {
    // entire message received
    // we got a message and it ends with a semicolon
    buffer[sofar]=0;  // end the buffer so string functions work right
    processCommand();  // do something with the command
  }

然后,processCommand()调用一个函数,该函数在缓冲区中搜索特定字符并返回直接在该字符后面的浮点数:

/**
 * Look for character /code/ in the buffer and read the float that immediately follows it.
 * @return the value found.  If nothing is found, /val/ is returned.
 * @input code the character to look for.
 * @input val the return value if /code/ is not found.
 **/
float parsenumber(char code,float val) {
  char *ptr=buffer;
  while(ptr && *ptr && ptr<buffer+sofar) {
    if(*ptr==code) { // if /code/ is found
      return atof(ptr+1); // return the float behind it
    }
    ptr=strchr(ptr,' ')+1; // else increment pointer to next char after a space
  }
  return val; // if the end of the buffer is reached, return the default value
} 

现在,此代码在Arduino Mega上运行良好,但在Due由于某些原因从未退出while循环。

这是它在Mega上的工作方式:

GCode: G1;
Parsenumber: code:F val:288.46
####
ASCII Code at ptr: 71.00
String at ptr: G1;
String at buffer end: 
#####
ptr incremented
ASCII Code at ptr: 0.00
String at ptr: 
String at buffer end: 
#####
End of Parse: return 288.46

但这是到期日的方式:

GCode: G1;
Parsenumber: code:F val:288.46
#####
ASCII Code at ptr: 71.00
String at ptr: G1;
String at buffer end: 
#####
ptr incremented
ASCII Code at ptr: 128.00
String at ptr: € q 
String at buffer end: 
#####
ptr incremented
ASCII Code at ptr: 113.00
String at ptr: q 
String at buffer end: 
#####
ptr incremented
ASCII Code at ptr: 8.00
String at ptr: 
String at buffer end: 
#####
ptr incremented
ASCII Code at ptr: 128.00
String at ptr: € q 
String at buffer end: 
#####
ptr incremented
ASCII Code at ptr: 113.00
String at ptr: q 
String at buffer end: 
#####

等等...

因此,在我看来,退出条件ptr<buffer+sofar从未被满足。 不幸的是,我无法使用Arduino打印内存地址。 有人知道吗?

我发表评论以结束问题:

ptr=strchr(ptr,' ')+1;递增指针 是未定义的行为,因为strchr找不到返回NULL的字符。

您应先检查strchr return,然后再将其分配给ptr。

可能在Atmel平台上,地址NULL+1处有一个0x00 ,可以使您的代码正常工作。

另一个可能性(我在Arduino上非常strchr )是,如果找不到char,Atmel库中的strchr实现不会返回NULL 我看到了strchr实现,在这种情况下,如果找不到char,则返回的值是字符串的最后一个char。

确保while循环之前的buffer是有效字符串。 (也许arduino默认将值初始化为0-IDK。C不会,并且可能会导致无限循环并导致“ while循环永不退出”。)

char buffer[MAX_BUF];
// int sofar;
int sofar = 0;  // Initialize to 0. 

buffer[0] = 0;  // Add 

在while循环中,每次添加字符后都要添加一个空字符。 这应该特别重要; 找不到或缓冲区很长。 while循环后不发布buffer会发生什么。

if (sofar<MAX_BUF-1) {
  buffer[sofar++] = c;
  buffer[sofar] = 0; // Add
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM