Hallo GCC-Gemeinde,
ich bin gerade auf ein sehr merkwürdiges Problem gestoßen. Und zwar
werden globale Variablen, die ich in meinem Programmcode nicht explizit
verwende, nicht richtig initialisiert, d.h. mit unbestimmten Werten.
Minimalbeispiel:
1 | /* Keine dieser Varianten funktioniert */
|
2 | uint32_t test = 5;
|
3 | //volatile uint32_t test = 5;
|
4 | //const uint32_t test = 5;
|
5 | //static const uint32_t test = 5;
|
6 |
|
7 | int main(void) {
|
8 | code
|
9 | code
|
10 | /* Irgendwo ein Breakpoint um mal in den Speicher zu schauen */
|
11 | code
|
12 | }
|
Jetzt das Gleiche mit einer Verwendung:
1 | int main(void) {
|
2 | code
|
3 | /* Breakpoint */
|
4 | code
|
5 | uint32_t asdf = test;
|
6 | code
|
7 | }
|
Und siehe da - nun wird die Variable test korrekt initialisiert. Ich
schließe daraus, dass mein Linker-Skript und der Startup-Code richtig
ist, da prinzipiell funktioniert die Initialisierung ja.
Weiß jemand, wo der Fehler liegen könnte? Die Optimierung ist jedenfalls
auf 0 gestellt (-O0).
Man stellt sich natürlich jetzt die berechtigte Frage, wozu mich das
überhaupt interessiert, wenn ich die Variable eh nicht verwende,
allerdings war das oben ja ein Minimalbeispiel. Falls es konkret von
Bedeutung ist:
Ich setze in meinem Linker-Skript ein Symbol an der Position, wo sich
eine Vektortabelle für nen Cortex-M3 befindet und möchte im laufenden
Betrieb die NVIC-Tabelle wechseln. Das geht dann mit
1 | extern uint32_t _isr_vectorsflash_offs;
|
2 | void NVIC_Configuration(void) {
|
3 | NVIC_SetVectorTable(NVIC_VectTab_FLASH, (uint32_t)&_isr_vectorsflash_offs);
|
4 | }
|
so habe ich das im Code für den STM32 MINI Digital Picture Frame von
Martin Thomas gefunden. Warum das & an den Funktionsparameter muss, ist
mir nicht ganz klar. Jedenfalls steht in _isr_vectorsflash_offs ständig
0x20005000, was definitiv nicht die Position der Vektortabelle im Flash
ist.
Vielleicht könnte ich das jetzt mit einer Fake-Verwendung der Variablen
umgehen, das habe ich noch nicht probiert, das wäre aber eh eine mehr
oder weniger unbefriedigende Lösung.
Ach ja: Die Optimierung ist natürlich aus, hier meine GCC-Argumente aus
dem Makefile:
1 | C_FLAGS = -mcpu=cortex-m3 -mthumb -O0 -gdwarf-2 \
|
2 | $(patsubst %,-I%,$(INC_DIRS)) -I. \
|
3 | -std=gnu99 \
|
4 | -ffunction-sections -fdata-sections \
|
5 | -Wall -Wextra -Wimplicit -Wcast-align -Wpointer-arith \
|
6 | -Wredundant-decls -Wshadow -Wcast-qual -Wcast-align -Wnested-externs \
|
7 | -Wno-cast-qual -Wno-missing-prototypes -Wno-strict-prototypes -Wno-missing-declarations
|
Kann mir jemand das Verhalten erklären oder weiß Abhilfe?
Vielen Dank und viele Grüße, Oliver.