Hallo Leute, ich versuche ein globales Array anzulegen : "volatile unsigned char test[32]" Wenn ich diese Array im Watchwindow anzeige wird es auf 4 Elemente beschränkt. Jedes Array größer 4 wird abgeschnitten. Egal ob global oder lokal angelegt. Kennt jemand dieses Problem? Kann es an einem Speichermodell liegen? Ich arbeite mit AVR-Studio 3.53. Vielen Dank Gruß Boris
hmm. kann eigentlich nur an avrstudio liegen. ich hatte schon größere arrays, die ham gefunzt (in der schaltung)... kann sein, dass das avrs die abschneidet.(?)
Hallo Boris, nach fast zehn Jahren bin ich mit Eclipse 3.7.2, avr-gcc 4.5.3, atmega8 und avrdude 5.11.1 auf das selbe Problem gestoßen. Ich konnte den Fehler umgehen indem ich das Array nicht bei der deklaration initialisiere, sondern erst nach der deklaration. Fehler: uint8_t array[] = {1, 2, 3, 4, 5, 6}; kein Fehler: uint8_t array[6]; array[0] = 1; array[1] = 2; ... ich kann mir nicht erklären wieso dieser Fehler(ohne Fehlermeldung) auftritt da ich mich noch so gut wie gar nicht mit compilern auskenne und mein simulavr auch nicht laufen will. Gruß und ein großes Dankeschön an die Mikrocontroller.net Community!!! Yalcin
Yalcin schrieb: > Hallo Boris, > > nach fast zehn Jahren bin ich mit Eclipse 3.7.2, avr-gcc 4.5.3, atmega8 > und avrdude 5.11.1 auf das selbe Problem gestoßen. > Ich konnte den Fehler umgehen indem ich das Array nicht bei der > deklaration initialisiere, sondern erst nach der deklaration. > > Fehler: uint8_t array[] = {1, 2, 3, 4, 5, 6}; > > kein Fehler: > uint8_t array[6]; > array[0] = 1; > array[1] = 2; > ... Die zweite Variante ist wesentlich ineffizienter als die erste. Sollte man sowas verwenden, nur weil eine IDE zu dumm [tm] ist, das korrekt anzuzeigen? > ich kann mir nicht erklären wieso dieser Fehler (ohne Fehlermeldung) Das gibt keine Fehlermeldung weil es kein Fehler ist.
Um was für einen "Fehler" geht es überhaupt? Da Eclipse eine komplett andere IDE ist, kann es ja wohl kaum wirklich um den gleichen Fehler wie im 10 Jahren alten OP gehen.
Für die erste Variante wird ein Literal angelegt, für die zweite nicht. Das gilt sowohl für auto Variablen als auch für solche im static Storage. Zumindest bei GCC.
Johann L. schrieb : >Das gibt keine Fehlermeldung weil es kein Fehler ist. Aber es ist doch eindeutig das wenn ich ein Array deklariere und initialisiere ich anschließend auf alle Elemente zugreifen können muss. Wie gesagt funktioniert die gleiche Struktur mit einem Elemente(Array) <= 4. Stefan Ernst schrieb: >Da Eclipse eine komplett andere IDE ist, kann es ja wohl kaum wirklich >um den gleichen Fehler wie im 10 Jahren alten OP gehen. Das kann ich nicht mit sicherheit sagen aber der Tenor ist der gleiche. Ich habe Tage verbracht diesen Fehler zu finden. Hoffe es kann behilflich sein. Gruß Yalcin
Yalcin schrieb: > Johann L. schrieb : >>Das gibt keine Fehlermeldung weil es kein Fehler ist. > > Aber es ist doch eindeutig das wenn ich ein Array deklariere und > initialisiere ich anschließend auf alle Elemente zugreifen können muss. > Wenn ich diese Array im Watchwindow anzeige wird es auf 4 > Elemente beschränkt. rein aus C-Warte gesehen, ist nichts Falsches in deinem Code. Wenn es sich um ein Problem handelt, dass der Debugger irgendwas nicht anzeigen kann oder deine IDE da irgendwas abartiges macht, dann muss man in diese Richtung weitergehen. Aber aus C-Sicht gibt es keinen Grund, warum es da in einem laufenden C-Programm ein Problem geben sollte. > ich kann mir nicht erklären wieso dieser Fehler(ohne Fehlermeldung) > auftritt da ich mich noch so gut wie gar nicht mit compilern auskenne > und mein simulavr auch nicht laufen will. Da gibts deswegen keine Fehlermeldung, weil es sich auch um keinen Programmfehler handelt. Das ist irgendwas in deinem Debugger oder deiner IDE. irgendeine Einstellung (oder auch ein Bug, obwohl ich letzters nicht wirklich glaube) Du musst unterscheiden zwischen Fehlern die du in dein Programm einbaust und Fehlern die in den von dir verwendeten Werkzeugen existieren.
Johann L. schrieb: > Für die erste Variante wird ein Literal angelegt, für die zweite nicht. Ja, und? Variante 2 dürfte unter anderem deshalb eher deutlich schneller sein (ich würde mal überschlagsmäßig mit Faktor 2-3 rechnen), allerdings auch speicherintensiver.
@boris: Kannst du denn im Debugger einzelne Array-Elemente mit Index >= 4 anzeigen lassen, also bspw. array[4] oder array[31]? Wenn ja: Werden die erwarteten Werte angezeigt? Wenn ja: Dann handelt es sich wohl tatsächlich um ein reines Anzeigeproblem im Debugger bzw. AVR-Studio.
Yalcin schrieb: > Aber es ist doch eindeutig das wenn ich ein Array deklariere und > initialisiere ich anschließend auf alle Elemente zugreifen können muss. > Wie gesagt funktioniert die gleiche Struktur mit einem Elemente(Array) > <= 4. "Funktioniert" in welcher Hinsicht? Reden wir hier wirklich von einem IDE/Debugger-Anzeige-Problem (wie im OP), oder vielleicht doch von einem Runtime-Problem (Programm funktioniert, oder funktioniert nicht)? Wenn Letzteres, dann tippe ich auf ".data-Section nicht ins Hex-File exportiert".
Rolf Magnus schrieb: > Johann L. schrieb: >> Für die erste Variante wird ein Literal angelegt, für die zweite nicht. > > Ja, und? Variante 2 dürfte unter anderem deshalb eher deutlich schneller > sein (ich würde mal überschlagsmäßig mit Faktor 2-3 rechnen), allerdings > auch speicherintensiver. Daß Variabte 2 ist für globale und statischen Variablen eben nicht wirklich schneller. Grund: Variante 1 initialisiert zum init-Zeit vor main, während Variante 2 erst dann läuft, wenn die Anwendung bereits gestartet ist. Ob es bis zu main ein paar µs länger dauert ist idR vollkommen Banane.
Vielleicht hat es was mit dem Umstand zu tun, dass die Größe des Arrays nicht explizit angegeben wurde. Das war ja mal eine GCC-eigene Erweiterung (inzwischen ist das in irgendeinem neueren C-Standard, IIRC). Passiert das immer noch, wenn man sowas macht:
1 | uint8_t array[6] = { 1, 2, 3, 4, 5, 6 }; |
Was übrigens die Effizienz angeht: Initialisierte Variablen werden vor dem Aufruf von main() in einer Schleife aus dem Flash initialisiert (ins RAM kopiert). Manuelle Initialisierung geschieht erst zu dem Zeitpunkt, zu dem man die Zeilen ausführt und kann sowohl mehr als auch weniger Flash-Bytes verbrauchen, je nach genauen Datentypen und Größe der Konstanten. Automatische Initialisierung durch GCC verhindert versehentlichen Zugriff auch noch uninitialisierte Variablen (unbezahlbar!), spart Zeilen im Quelltext (auch wichtig!), ggf. Flash-Bytes (die paar sind nicht so wichtig), kostet aber Zeit bis zum Aufruf von main (meist vollkommen unwichtig -- wenn's sehr schnell losgehn muss, nimmt man einen Sleep-Modus). Das Manuelle ist die Mühen also nicht wert. Nur wegen einem Bug im Debugger (welch Ironie!) sollte man sich seinen Quelltext nicht verunstalten.
Stefan Ernst schrieb: >>Yalcin schrieb: >> Aber es ist doch eindeutig das wenn ich ein Array deklariere und >> initialisiere ich anschließend auf alle Elemente zugreifen können muss. >> Wie gesagt funktioniert die gleiche Struktur mit einem Elemente(Array) >> <= 4. >"Funktioniert" in welcher Hinsicht? Reden wir hier wirklich von einem >IDE/Debugger-Anzeige-Problem (wie im OP), oder vielleicht doch von einem >Runtime-Problem (Programm funktioniert, oder funktioniert nicht)? > >Wenn Letzteres, dann tippe ich auf ".data-Section nicht ins Hex-File >exportiert". Ich gehe auch davon aus das -ich nenne es meinen nicht erfüllten Willen- an der .data-Section liegt. Ich weiß nicht wie ich damit umgehen soll bzw. kenn solche Segmentierungen nur aus dem Mikrocontroller.net Assembler Tutorial in dem aber nicht beschrieben ist wie ein compiler das erledigt. (..."man gcc" schau ich mir ein anderes mal an) :D
1 | **** Build of configuration Release for project Pedelec **** |
2 | |
3 | make all |
4 | Building file: ../lcd.c |
5 | Invoking: AVR Compiler |
6 | avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega8 -DF_CPU=8000000UL -MMD -MP -MF"lcd.d" -MT"lcd.d" -c -o "lcd.o" "../lcd.c" |
7 | ../lcd.c: In function ‘init_lcd’: |
8 | ../lcd.c:170:2: warning: implicit declaration of function ‘blinken’ |
9 | Finished building: ../lcd.c |
10 | |
11 | Building file: ../main.c |
12 | Invoking: AVR Compiler |
13 | avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega8 -DF_CPU=8000000UL -MMD -MP -MF"main.d" -MT"main.d" -c -o "main.o" "../main.c" |
14 | Finished building: ../main.c |
15 | |
16 | Building file: ../spi.c |
17 | Invoking: AVR Compiler |
18 | avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega8 -DF_CPU=8000000UL -MMD -MP -MF"spi.d" -MT"spi.d" -c -o "spi.o" "../spi.c" |
19 | Finished building: ../spi.c |
20 | |
21 | Building target: Pedelec.elf |
22 | Invoking: AVR C Linker |
23 | avr-gcc -Wl,-Map,Pedelec.map --gc-sections -mmcu=atmega8 -o "Pedelec.elf" ./Pedelec/.metadata/.plugins/org.eclipse.cdt.make.core/specs.o ./.metadata/.plugins/org.eclipse.cdt.make.core/specs.o ./adc.o ./globalflag.o ./initialisierung.o ./interrupt.o ./lcd.o ./main.o ./mathfunction.o ./sinuskommutierung.o ./spi.o ./timer.o |
24 | Finished building target: Pedelec.elf |
25 | |
26 | Create Flash image (ihex format) |
27 | avr-objcopy -R .eeprom -O ihex Pedelec.elf "Pedelec.hex" |
28 | Finished building: Pedelec.hex |
29 | |
30 | Invoking: Print Size |
31 | avr-size --format=avr --mcu=atmega8 Pedelec.elf |
32 | AVR Memory Usage |
33 | ---------------- |
34 | Device: atmega8 |
35 | |
36 | Program: 6980 bytes (85.2% Full) |
37 | (.text + .data + .bootloader) |
38 | |
39 | Data: 1272 bytes (124.2% Full) <---- verdächtig? |
40 | (.data + .bss + .noinit) |
41 | |
42 | |
43 | Finished building: sizedummy |
44 | |
45 | |
46 | **** Build Finished **** |
Übrigens werde ich wenn ich mit meinem Pedelec fertig bin hier alles als OpenSource freigeben. Falls ihr Tipps für mich habt bin ich dankbar. zur Zeit Versuch ich erstmal die Kommunikation auf die Beine zu stellen (zwecks Debbugen mit "7 Segmentanzeige"). Die Struktur -als Konzept- der Motorsteuerung mit PWM, verketteter Liste, etc. steht so ungefähr.
Johann L. schrieb: > Daß Variabte 2 ist für globale und statischen Variablen eben nicht > wirklich schneller. Grund: Variante 1 initialisiert zum init-Zeit vor > main, während Variante 2 erst dann läuft, wenn die Anwendung bereits > gestartet ist. Und welchen Unterschied macht es, ob das nun vor main() oder direkt am Anfang von main() gemacht wird? Warum sollte es mehr Zeit brauchen, wenn es in main() gemacht wird statt davor? > Ob es bis zu main ein paar µs länger dauert ist idR vollkommen Banane. Das ist allerdings richtig, aber es war ja deine Aussage, daß die Zuweisungen in main() erheblich länger dauern sollen.
Johanns Aussage
> Die zweite Variante ist wesentlich ineffizienter als die erste.
bezog sich natürlich auf die Speichereffizienz, nicht auf die
Rechenzeiteffizienz ;-)
Yalcin schrieb: > Data: 1272 bytes (124.2% Full) <---- verdächtig? > (.data + .bss + .noinit) Das kracht definitiv. Je nach Abschätzung des Stackverbrauchs sollten da max 80% stehen. Peter
SOodann schließ ich mal mit einer Lösung das Problem ab. Also, ich habe in Eclipse nicht benötigte Dateien mit "exclude from Project" aus dem Projekt ausgeschlossen. Ich war der meineung das nicht inkludierte *.c bzw. *.h Dateien vom Compiler automatisch ausgeschlossen werden. Gruß Yalcin
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.