简体   繁体   English

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

[英]Infinite loop due to Pointers on Arduino Due

I implemented a buffer on Arduino Mega 2560 using Code of Dan Royer as a base. 我以Dan Royer的代码为基础在Arduino Mega 2560上实现了一个缓冲区。 The code runs perfectly fine on the Mega, but I wanted to use the enhanced features and power of the Arduino Due (which uses an ARM instead of the standard Atmel microprocessor). 代码在Mega上运行得非常好,但是我想使用Arduino Due(使用ARM而不是标准Atmel微处理器)的增强功能和强大功能。

On the Due I always get into an infinite loop while processing the buffer content due to it not exiting when the end of the buffer is reached. 在Due上,由于在到达缓冲区末端时不退出缓冲区内容,因此在处理缓冲区内容时,我总是陷入无限循环。 Does anyone know why this might happen? 有谁知道为什么会这样? And do you have ideas on how to prevent this? 您对如何防止这种情况有想法吗?

The commands given would be GCodes such as : "G01 X20.5 Y30;" 给出的命令将是GCode,例如:“ G01 X20.5 Y30;”。

This is how the buffer is filled: 这是缓冲区填充的方式:

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
  }

The processCommand() then calls a function that searches the buffer for specific characters and returns the float that is directly behind this character: 然后,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
} 

Now, this code works perfectly fine on the Arduino Mega, but on the Due the while loop is never exited for some reason. 现在,此代码在Arduino Mega上运行良好,但在Due由于某些原因从未退出while循环。

This is how it works on the Mega: 这是它在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

But this is how it is on the Due: 但这是到期日的方式:

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: 
#####

and so on... 等等...

Thus, it seems to me that the exit condition ptr<buffer+sofar is never met. 因此,在我看来,退出条件ptr<buffer+sofar从未被满足。 Unfortunately I have not been able to print memory addresses with the Arduino. 不幸的是,我无法使用Arduino打印内存地址。 Does anyone know anything? 有人知道吗?

I post my comment to allow to close the question: 我发表评论以结束问题:

Incrementing pointer with ptr=strchr(ptr,' ')+1; ptr=strchr(ptr,' ')+1;递增指针 is undefined behaviour, because of strchr doesn't find the char it return NULL . 是未定义的行为,因为strchr找不到返回NULL的字符。

You should check strchr return, before to assign it to ptr. 您应先检查strchr return,然后再将其分配给ptr。

Probably on Atmel platform, there is a 0x00 at address NULL+1 that make your code work well. 可能在Atmel平台上,地址NULL+1处有一个0x00 ,可以使您的代码正常工作。

Another possibility (I'm very noob on Arduino) is that strchr implementation in Atmel library is not returning NULL if the char is not found. 另一个可能性(我在Arduino上非常strchr )是,如果找不到char,Atmel库中的strchr实现不会返回NULL I saw strchr implementation where, in case of char not found, the returned value was last char of string. 我看到了strchr实现,在这种情况下,如果找不到char,则返回的值是字符串的最后一个char。

Insure buffer is a valid string before the while loop. 确保while循环之前的buffer是有效字符串。 (Maybe arduino initializes values to 0 by default - IDK. C does not and an infinite loop may result and cause "while loop is never exited".) (也许arduino默认将值初始化为0-IDK。C不会,并且可能会导致无限循环并导致“ while循环永不退出”。)

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

buffer[0] = 0;  // Add 

During the while loop, append a null character after each time a character is appended. 在while循环中,每次添加字符后都要添加一个空字符。 This is especially important should a ; 这应该特别重要; is not found or the buffer is long. 找不到或缓冲区很长。 Is is not posted what happens to buffer after the while loop. 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