-
-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using RTClib and Time libraries together produces garbage dates due to gcc's const data merging #59
Comments
I tried to create a wrapper for all the binaries containing the string #!/bin/sh
exec $0.real "$@" -fno-merge-constants -fno-merge-all-constants -O0
but it did not help (only triggering a warning from |
Please give it a try using the beta test version of the upcoming Arduino AVR Boards toolchain, which uses avr-gcc 7.3.0:
Using the sketch you provided with Arduino AVR Boards 1.6.23 (avr-gcc 5.4.0), I also get an incorrect value for Can we use the following code as a shorter and less convoluted demonstration of the issue? const uint8_t numbers[] = {1, 2, 3, 4, 5};
const uint8_t progmemNumbers[] PROGMEM = {1, 2, 3, 4, 5};
void setup() {
Serial.begin(9600);
Serial.print("numbers: ");
for (uint8_t i = 0; i < sizeof(numbers); i++) {
Serial.print(numbers[i]);
}
Serial.println();
Serial.print("progmemNumbers: ");
for (uint8_t i = 0; i < sizeof(progmemNumbers); i++) {
Serial.print(pgm_read_byte(&progmemNumbers[i]));
}
}
void loop() {} Result with Arduino AVR Boards 1.6.23:
Result with Arduino AVR Boards 1.6.209:
|
Thanks, yes updating to AVR boards 1.6.209 makes the problem go away. |
Problem still exists in gcc 7.3.0. |
I initially intended to have the title "g++ incorrectly merges PROGMEM and non-PROGMEM data", but opted to focus on the consequences since I think this is a really bad show stopper bug.
The TL;DR version is that because library file
RTClib.cpp
contains (usingPROGMEM
)and library file
Time.cpp
contains (not usingPROGMEM
)the compiler incorrectly merges them, but due to the micro-controller's modified Harvard architecture they are stored in different memory types and cannot be accessed the same way. Attempts to read one of them will result in garbage data.
Initially I debugged the problem by adding some
Serial.print
toTime.cpp
andRTClib.cpp
and discovered that inTime.cpp
the number of days in a month were garbage values comming from itsmonthDays
array.I managed to reproduce similar behaviour in a standalone sketch, without requiering modifications of libraries.
When compiled it produces warning
warning: uninitialized variable 'monthDays2' put into program memory area [-Wuninitialized] const uint8_t monthDays2[] PROGMEM = { ^
but I do not understand why it does not also complain about
month_days1/2
andprimes1/2
, they should have the same issue.Initially I thought that this might have something to do with the actual access to the variable through the specific assembly instruction (hence also inlining the macro just to see if it made any difference (which it did not)), but it turns out that with the
#if
s disabled the variable is just optimized away. Just referencing the variable likewill keep it in the translation unit and produce the same issue. Running the above code on an Arduino Uno gives the following, notice the garbage value for
days
below:I guess this problem is related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80462.
I have tested compiling and flashing both with Arduino studio 1.8.8 & nightly (and with vscode, although it is just reusing the toolchain from the Arduino IDE). I have tested on two different computers. And I have tested with two different arduino boards.
The nightly build also uses 5.4.0-atmel3.6.1-arduino2, so no difference.
The text was updated successfully, but these errors were encountered: