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_tarray[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 ****
Ü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