mikrocontroller.net

Forum: Compiler & IDEs Array > 4


Autor: boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.(?)

Autor: Yalcin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Die zweite Variante ist wesentlich ineffizienter als die erste.

Warum?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yalcin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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".

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Sam P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
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.

Autor: Yalcin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
**** Build of configuration Release for project Pedelec ****

make all 
Building file: ../lcd.c
Invoking: AVR Compiler
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"
../lcd.c: In function ‘init_lcd’:
../lcd.c:170:2: warning: implicit declaration of function ‘blinken’
Finished building: ../lcd.c
 
Building file: ../main.c
Invoking: AVR Compiler
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"
Finished building: ../main.c
 
Building file: ../spi.c
Invoking: AVR Compiler
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"
Finished building: ../spi.c
 
Building target: Pedelec.elf
Invoking: AVR C Linker
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   
Finished building target: Pedelec.elf
 
Create Flash image (ihex format)
avr-objcopy -R .eeprom -O ihex Pedelec.elf  "Pedelec.hex"
Finished building: Pedelec.hex
 
Invoking: Print Size
avr-size --format=avr --mcu=atmega8 Pedelec.elf
AVR Memory Usage
----------------
Device: atmega8

Program:    6980 bytes (85.2% Full)
(.text + .data + .bootloader)

Data:       1272 bytes (124.2% Full)  <---- verdächtig?
(.data + .bss + .noinit)


Finished building: sizedummy
 

**** 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johanns Aussage

> Die zweite Variante ist wesentlich ineffizienter als die erste.

bezog sich natürlich auf die Speichereffizienz, nicht auf die
Rechenzeiteffizienz ;-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Yalcin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.