I have an Arduino project where I read data from a webserver.
I have an EthernetClient that reads the data character by character in a callback function.
My working code looks like (only the relevant parts):
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);
}
...
}
This works without any problems (reading and processing the data), but when I remove Serial.begin(9600); and Serial.print(c); it stops working and I don’t know why? The only thing changed is that the char c is not printed. What could be the problem?
A common reason why callback functions change their behavior when seemingly unrelated code is altered, is optimizer-related bugs.
Many embedded compilers fail to understand that a callback function (or an interrupt service routine) will ever be called in the program. They see no explicit call to that function and then assumes it is never called.
When the compiler has made such an assumption, it will optimize variables that are changed by the callback function, because it fails to see that the variable is changed by the program, between the point of initialization and the point of access.
When this bug strikes, it is nearly impossible to find, it can cause any kind of weird symptoms.
The solution is to always declare all file scope (“global”) variables shared between main() and an interrupt/callback/thread as
volatile. This makes it impossible for the compiler to make incorrect optimizer assumptions.(Please note that the
volatilekeyword cannot be used to achieve synchronization nor does it guarantee any memory barriers. This answer is not in the slightest related to such issues!)