0

我是 C++ 的初学者,正在尝试为我的 Arduino 创建一个程序。下面的代码编译得很好,但结果与我预期的不同。

我希望在我的 PC 上收到的是:0x04、0x61、0x62、0x63。

我在 PC 上收到的是:0xff 0x00 0xb1 0x00。

我试图以一种只解决我遇到的问题的方式最小化代码。

byte *assembleFrame() {
  byte frame[] = { 4 , 'a' , 'b' , 'c' , 'd' };
  return frame;
}

void setup() {
  Serial.begin( 115200 );
};

void loop() {
  byte *frame = assembleFrame();
  Serial.write( frame , 4 );
  // should send 0x04 0x61 0x62 0x63, leaving out 0x64 being 5th element.
  while ( 1 ) {
  }
}

我认为它与指针有关,但无法弄清楚。

供参考:

Serial.write( buf , len ) arguments:    
  buf: an array to send as a series of bytes
  len: the length of the buffer

编辑: 到目前为止的解决方案:

int assembleFrame( byte *frame ) {
  int octetCounter = 0;
  frame[ octetCounter++ ] = 'A'; // preamble
  frame[ octetCounter++ ] = 'B'; // preamble
  frame[ octetCounter++ ] = 0;   // frame length set at end of function
  frame[ octetCounter++ ] = h;
  frame[ octetCounter++ ] = m;
  frame[ octetCounter++ ] = s;
  frame[ 2 ] = octetCounter;  // frame length

  return frame[ 2 ];
}

void loop() {
  int bytes_in_frame = assembleFrame( frame );
  Serial.write( frame, bytes_in_frame ); // assuming ptr + bytes to send
  delay( 1000 );
}

它给出了预期的结果。

4

3 回答 3

3

+ Krister 的回答很好,如果可能的话,我会建议您将缓冲区传递到您的汇编函数中来改进它。

/* Takes in an array of bytes with at least the given size, returns
 * the number of bytes written into the frame.
 */
int assembleFrame(byte *frame, int frame_size) {
  frame[0] =  4;
  frame[1] = 'a';
  frame[2] = 'b';
  frame[3] = 'c';
  frame[4] = 'd';
  return 5; // only used five bytes in the frame
}

  /* then in loop() */
  byte frame[10];
  bytes_in_frame = assembleFrame(frame, 10);
  someDataSendingFunction(frame, bytes_in_frame); // assuming ptr + bytes to send

这样您就不会在以后产生内存泄漏的可能性。

于 2012-04-09T20:42:52.060 回答
1

您的 assembleFrame() 函数返回一个局部变量,该变量将在函数返回时超出范围。你可以这样做:

 byte* assembleFrame() {
      byte* frame = new byte[5];
      frame[0] = 4;
      frame[1] = 'a';
      frame[2] = 'b';
      frame[3] = 'c';
      frame[4] = 'd';
      return frame;
 }

请注意,应使用 assembleFrame() 返回的内存:

void loop() {
   byte* frame = assembleFrame();
   Serial.write( frame , frame[ 0 ] );
   // release the memory allocated by assembleFrame()
   delete [] frame;
   while ( 1 ) {
   }
}
于 2012-04-09T20:32:17.287 回答
0

首先,正如所说,你现在有悬空指针和欠精细的行为。如果您启用警告(-Wall),您将获得

警告:返回局部变量“frame”的地址

就目前而言,由于 Arduino 正在嵌入,并且由于资源限制,使用动态动态内存管理与嵌入(您甚至不能默认调用 new ,呵呵)不愉快,您可能需要使用以下灵魂:

  1. 制作frame静态:

    char *assembleFrame() {
        static char frame[] = { 'a' , 'b' , 'c' , 'd', 0 };
        return frame;
    }
    

    当然,如果您在assembleFrame调用后更改代码中的数组,这种更改将持续存在。

  2. 制作frame const指针并返回字符串

    const char *assembleFrame() {
        const char* frame = "abcd\0";
        return frame;
    }
    
于 2012-04-09T20:53:03.303 回答