4

我有一个 Arduino 项目,我从网络服务器读取数据。

我有一个EthernetClient在回调函数中逐字符读取数据的方法。

我的工作代码看起来像(只有相关部分):

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

void loop() {
  char* processedData = processData(callback); // this is in a external lib
}

boolean callback(char* buffer, int& i) {
  ...

  if (Client.available()) {
    char c      = client.read();
    buffer[i++] = c;

    Serial.print(c);
  }

  ...
}

这可以正常工作(读取和处理数据),但是当我删除它Serial.begin(9600);Serial.print(c);停止工作并且我不知道为什么?唯一改变的char c是没有打印。可能是什么问题呢?

4

2 回答 2

2

当看似无关的代码被更改时,回调函数改变其行为的一个常见原因是与优化器相关的错误。

许多嵌入式编译器无法理解回调函数(或中断服务例程)将在程序中被调用。他们看不到对该函数的显式调用,然后假设它从未被调用过。

当编译器做出这样的假设时,它会优化被回调函数改变的变量,因为它看不到变量在初始化点和访问点之间被程序改变了。

// Bad practice example:

int x; 

void main (void)
{
  x=5;
  ...

  if(x == 0) /* this whole if statement will get optimized away, 
                the compiler assumes that x has never been changed. */
  {
    do_stuff();
  }
}

void callback (void)
{
  x = 0;
}

当这个错误发生时,几乎不可能找到它,它可能会导致任何奇怪的症状。

解决方案是始终将 main() 和中断/回调/线程之间共享的所有文件范围(“全局”)变量声明为volatile. 这使得编译器不可能做出不正确的优化器假设。


(请注意,该volatile关键字不能用于实现同步,也不保证任何内存屏障。这个答案与此类问题没有丝毫关系!

于 2012-12-19T15:49:58.583 回答
0

一个猜测:因为没有启动串行驱动程序,没有数据要处理,因此你的回调没有命中。

您希望串行回调在没有数据的情况下做什么?

提供更多信息可能ClientprocessData有所帮助。

于 2012-12-19T13:44:08.820 回答