从 Windows 或 Linux 编译的 Arduino 草图表现不同

问题描述 投票:0回答:1

我有一个非常奇怪的问题,如果从 Windows XP Home sp3 或 Elementary OS Luna(Ubuntu Linux 的发行版)编译并上传到 Arduino,该草图的性能会有所不同。

除其他事项外,该草图从串行连接(蓝牙)读取一个字节并将其写回串行监视器。

这是我从 WinXP 编译草图时得到的结果:我通过 BT 连接字符串从“1”到“7”每次发送一次。这些字符串的 ASCII 码减少了 48,以将字符串转换为字节。结果是正确的,指针数组中的函数也被正确调用。 enter image description here

这是我从 Linux 得到的信息。我将每个字符串从“1”到“7”发送了 4 次,以查看结果与我需要获得的内容无关,并且与相同的输入数据不一致:例如,当我发送字符串“2”时,我得到104 106 106 104..... 相同的字节 106 是用来自 BT 的不同字符串写入的。 此外,这些函数没有被调用,因此这意味着这不是 Serial.print 问题。

enter image description here

我确定这是一个编译问题,因为一旦将草图上传到 Arduino,如果我在 WinXP 或 Linux 中使用串行监视器,它就会以相同的方式执行(无论正确与否)。

这是草图

#include "Arduino.h"
#include <SoftwareSerial.h>
#include <Streaming.h>
#define nrOfCommands 10

typedef void (* CmdFuncPtr) (); // this is a typedef to command functions

//the following declares an arry of 10 function pointers of type DigitFuncPtr 
CmdFuncPtr setOfCmds[nrOfCommands] = {
  noOp,
  leftWindowDown,
  leftWindowUp,
  bootOpen,
  cabinLightOn,
  cabinLightOff,
  lockOn,
  lockOff,
  canStart,
  canStop
};


#define cmdLeftWindowDown 1
#define cmdLeftWindowUp 2
#define cmdBootOpen 3
#define cmdCabinLightOn 4
#define cmdCabinLightOff 5
#define cmdLockOn 6
#define cmdLockOff 7
#define cmdCanStart 8
#define cmdCanStop 9

#define buttonPin  4     // the number of the pushbutton pin
#define bluetoothTx 2
#define bluetoothRx 3

int buttonState = 0;         // variable for reading the pushbutton status
int androidSwitch=0;

byte incomingByte;  // incoming data
byte msg[12];
byte msgLen=0;
byte msgIdMsb=0;
byte msgIdLsb=0;

//const byte cmdLeftWindowDown;

SoftwareSerial bluetooth(bluetoothTx,bluetoothRx);

void setup()
{
  //Setup usb serial connection to computer
  Serial.begin(115200);

  //Setup Bluetooth serial connection to android
  bluetooth.begin(115200);
  //bluetooth.print("$$$");

  randomSeed(analogRead(10));
  delay(100);
  //bluetooth.println("U,9600,E");
  //bluetooth.begin(9600);
  //time=0;
}

void loop() {
  msgIdLsb=random(1,255);
  msgIdMsb=random(0,5);
  msg[0]=msgIdMsb;
  msg[1]=msgIdLsb;
  msgLen=random(9);
  msg[2]=msgLen;

  for (int x=3;x<msgLen+3;x++) {
    msg[x]=random(255);
  }

  for (int x=3+msgLen;x<11;x++) {
    msg[x]=0;
  }
  msg[11]='\n';
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  if ((buttonState == HIGH)||(androidSwitch==HIGH)) {  
    for (int x=0;x<12;x++) {
      Serial<<msg[x]<<" ";
      bluetooth.write(uint8_t(msg[x]));
    }
    Serial<<endl;

  }

  //Read from bluetooth and write to usb serial
  if(bluetooth.available())
  {
    incomingByte = bluetooth.read()-48;
    Serial<<incomingByte<<endl;
    if (incomingByte<nrOfCommands)
      setOfCmds[incomingByte]();

  }

  delay(10);
}

void noOp(void)
{
  Serial<<"noOp"<<endl;
};

void leftWindowDown(void)
{
  Serial<<"leftWindowDown"<<endl;
};

void leftWindowUp(void)
{
  Serial<<"leftWindowUp"<<endl;
};

void bootOpen(void)
{
  Serial<<"bootOpen"<<endl;
};

void cabinLightOn(void)
{
  Serial<<"cabinLightOn"<<endl;
};

void cabinLightOff(void)
{
  Serial<<"cabinLightOff"<<endl;
};

void lockOn(void) 
{
  Serial<<"lockOn"<<endl;
};

void lockOff(void)
{
  Serial<<"lockOff"<<endl;
};

void canStart(void)
{
  androidSwitch=HIGH;
};

void canStop(void)
{
  androidSwitch=LOW;
};

任何帮助都会非常有帮助。 预先感谢。

linux arduino serial-port
1个回答
1
投票

我想你正在使用arduino ide;如果不是,以下某些内容可能不适用。

首先,找出ide在编译和链接代码时使用的构建目录的位置。 [找出答案的一种方法是在编译期间暂时打开详细输出。 (单击“文件”、“首选项”、“编译期间显示详细输出”。)单击“验证”按钮编译代码,然后查看输出第一行中 -o 选项后面的路径。] 例如,在 Linux 系统上构建目录路径可能类似于

/tmp/build3877126492387157498.tmp
。 在该目录中,查找编译期间创建的 .cpp 文件。

在两个系统上找到草图的 .cpp 文件后,将它们复制到一个系统上,以便您可以比较它们并检查差异。 如果它们不同,则一个或另一个 ide 可能已损坏,或者可能发生不正确的包含。

如果 .cpp 文件不同,请比较编译标志、头文件等。我认为两个系统上的标志和 AVR 头文件应该相同,但可能的例外是 MSW 文件在换行符后可能有回车符人物。 还要检查 gcc 版本。 [我没有可以尝试的 MSW 系统,但我假设两个系统上都使用 gcc 进行 AVR 交叉编译。 如果我错了请纠正我。]

如果 .cpp 文件匹配,则测试生成的二进制文件以找出它们的不同之处。 (例如,如果草图文件是

Blink21x.ino
,则二进制文件可能是
Blink21x.cpp.elf
Blink21x.cpp.hex
。)如果两个系统上都有.elf文件[我不知道MSW系统是否会生成.elf ] 在Linux系统上使用
avr-objdump
生成反汇编版本的代码:

avr-objdump -d Blink21x.cpp.elf > Blink21x.cpp.lst

然后使用

diff
来定位两个反汇编文件之间的差异。 如果差异是由于源代码的编译方式(而不是库中的差异)造成的,则 .lst 文件中提供了足够的信息来识别源代码行。 (在后一种情况下,.lst 文件中给出了足够的信息来识别哪些库例程不同。)

如果 MSW 系统上没有 .elf 文件,您可以尝试比较 .hex 文件。 从差异的位置,您可以在 Linux 系统 .elf-disassemble 文件中找到相关行,并从中识别出您的代码行或库例程。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.