Forum: Compiler & IDEs Atmel Studio 6 ignoriert Code


von Peder (Gast)


Lesenswert?

Hallo,

ich habe jetzt bestimmt 30 Minuten lang versucht, aus einer externen 
Datei zwei große Arrays einzubinden. Die externe Datei "array.c" sieht 
dabei so aus (die Punkte sind natürlich im Original irgendwelche Werte):
1
const static uint8_t flash_table_lb[19370] PROGMEM = {...};
2
const static uint8_t flash_table_lb[9685]  PROGMEM = {...};

Eingebunden habe ich die Datei so:
1
#include "array.c"

Wenn ich mir nach dem Build das lss-File ansehe, dann wurde das zweite 
Array immer wieder komplett ignoriert. Ich habe alles mögliche aus- und 
wieder "hinein"kommentiert (kenne das Gegenteil von auskommentieren 
nicht) und schließlich hat er ohne eigentliche Code-Änderungen beide 
Arrays im lss-File. Warum? Übersehe ich etwas oder ist Atmel Studio 
einfach so störrisch?


Grüße

Peter

von Alex (Gast)


Lesenswert?

Hallo,

dann schau dir doch mal genau deine beiden Variablennamen an.
Warum sollte das Atmel Studio die zweite Variable anlegen, wenn sie doch 
schon existiert.

Grüße Alex

von Peter II (Gast)


Lesenswert?

Peder schrieb:
> Eingebunden habe ich die Datei so:#include "array.c"

das macht man nicht. Man bindet mit include Header Dateien ein und nicht 
C Dateien. C Dateien linkt man dazu.

von Peder (Gast)


Lesenswert?

Ach Mann! Ich produziere diese Fehler immer erst, wenn ich hier Fragen 
stelle. In meinem Code heißen die Arrays natürlich nicht gleich. Sie 
enden auf "hb" und "lb". Ich habe die erste Zeile einfach nur kopiert, 
weil ich die zweite sonst im Code bei Zeile 20000 hätte suchen müssen 
und dann hab ich nur die Wertezahl geändert, nicht den Namen. Reine 
Nachlässigkeit.


> C Dateien linkt man dazu.

Ich sollte normalerweise selbst suchen, aber wo das Stichwort schon mal 
gefallen ist, geht das wahrscheinlich um Welten schneller: Wie linke ich 
etwas dazu? Ich hab diese "Extra-Tools" noch nie benutzt. Bisher hat es 
immer der Play-Button getan.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Peder schrieb:
>> Eingebunden habe ich die Datei so:#include "array.c"
>
> das macht man nicht.

In seinem Fall könnte das schon zielführend sein.
Nur nennt man die Datei dann nicht 'irgendwas.c', sondern gibt ihr eine 
andere Endung um anzudeuten, dass es sich nicht um kompletten C-Code 
handelt, sondern eine Art 'Zulieferer' für eine andere C-Datei ist.
Die Endung 'inc' ist da zb. sehr beliebt.

Anstelle von "array.c" würde man das File zb 'sinus_table.inc' nennen 
(denn dann sagt mir der Dateiname auch noch, welchen Zweck die in ihm 
enthaltenen Konstanten haben, wenn die Daten kein Sinus sind, sondern 
irgendwas anderes, dann eben einen anderen sinnvollen Namen), und im 
eigentlichen C-File kommt dann der Include dieses Tabellenfiles.

Da es dem #include ja grundsätzlich egal ist, was includiert wird, geht 
auch das hier

main.c
1
....
2
const static uint8_t flash_table_low[] PROGMEM =
3
{
4
#include "ProgammLow.inc"
5
};
6
7
const static uint8_t flash_table_high[]  PROGMEM =
8
{
9
#include "ProgrammHigh.inc"
10
};
11
...

so etwas kann manchmal einfacher sein, weil man dann kein 
Spezialprogramm braucht, welches beim Erzeugen der eigentlichen Daten 
den C-Teil korrekt davor setzen muss. In den Inc-Files steht dann 
tatsächlich nur der Array-Inhalt in C-Schreibweise.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Peder schrieb:

>> C Dateien linkt man dazu.
>
> Ich sollte normalerweise selbst suchen, aber wo das Stichwort schon mal
> gefallen ist, geht das wahrscheinlich um Welten schneller: Wie linke ich
> etwas dazu?

Kommt auf deine Entwicklungsumgebung an.

Im Grunde läuft es darauf hinaus, dass du deiner Entwicklungsumgebung 
klar machst, dass dein komplettes Programm aus mehreren C-Files besteht. 
Die Entwicklungsumgebung sorgt dann dafür, dass alle C-Files, die zum 
Projekt gehören einzeln compiliert werden und die so entstandenen 
Object-Files alle gemeinsam zum kompletten Programm zusammengelinkt 
werden.

Der Vorteil ist, dass dann immer nur die C-Files neu compiliert werden 
müssen, die sich bei Änderungen auch tatsächlich ändern.

Ob das in deinem Fall zielführend ist, musst du entscheiden. Deine 
Array-Größen lassen mich vermuten, dass der Array-Inhalt aus einem 
anderen Programm stammt. Zb aus irgendwelchen Excel-Tabellen oder so.

von Oliver (Gast)


Lesenswert?

Peder schrieb:
> Wenn ich mir nach dem Build das lss-File ansehe, dann wurde das zweite
> Array immer wieder komplett ignoriert.

Was allerdings völlig egal wäre, wenn sich das Programm fehlerfrei 
kompilieren und linken lässt. Gabs es da denn Fehlermeldungen?

Oliver

von Peder (Gast)


Lesenswert?

Diese Methode
1
const static uint8_t flash_table_lb[19370] PROGMEM =
2
{
3
    #include "array_lb.inc"
4
};
finde ich eigentlich recht elegant. Wenn ich das aber versuche, sagt er 
mir beim Build "invalid initializer" und bezieht sich auf die inc-Datei. 
In dieser stehen aber nur noch kommaseparierte Werte ohne jeglichen 
C-Code. Fehlt da noch etwas?


Zum Thema "Dazulinken"
Wenn das das gleiche ist wie "Add existing item" im Solution Explorer, 
dann führt das zu Problemen. Denn auf einmal will er in den 
dazugelinkten Dateien auch noch Headerdateien eingebungen haben. Auch 
wenn die in der main-Datei schon drin sind.


Alles in Allem habe ich aber mittlerweile wieder das Problem, dass immer 
nur ein Array eingebungen wird statt zwei. Das muss doch einen 
systematischen Fehler geben, den ich da mache. Immer nur auf den Zufall 
hoffen, dass es beim nächsten mal richtig compiliert, ist extrem lästig.


> Gabs es da denn Fehlermeldungen?
Nein, gar nichts. Nicht einmal Warnungen...

von Peder (Gast)


Lesenswert?

Peder schrieb:
> Wenn ich das aber versuche, sagt er
> mir beim Build "invalid initializer"

Ich hab einfach nur ein Zeichen in der main.c vergessen. Heißt, 
Fehlermeldung ist verschwunden.


Ich bin jetzt ziemlich sicher, dass das Problem selbst an irgendwelchen 
Optimierungen liegt. Irgendwann im Code gibt es eine Stelle, die -- wenn 
auskommentiert -- zu einer unbenutzten Variable führt. Es scheint 
reproduzierbar zu sein, dass immer nur das Array eingebunden wird, was 
später auch gebraucht wird. Damit dürfte meine Aussage bezüglich 
Warnmeldungen falsch gewesen sein.


Gibt es eine Möglichkeit, den Compiler (oder wen auch immer) dazu zu 
zwingen, die Daten gefälligst im Flash-Speicher meines µC abzulegen? Ich 
muss zu Testzwecken manchmal etwas auskommentieren und wenn dann der 
Rest wegoptimiert wird, hilft mir das recht wenig.

von Amateur (Gast)


Lesenswert?

>und wenn dann der
>Rest wegoptimiert wird, hilft mir das recht wenig.

Einfach die Optimierung abschalten.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peder schrieb:
> Gibt es eine Möglichkeit, den Compiler (oder wen auch immer) dazu zu
> zwingen, die Daten gefälligst im Flash-Speicher meines µC abzulegen? Ich
> muss zu Testzwecken manchmal etwas auskommentieren und wenn dann der
> Rest wegoptimiert wird, hilft mir das recht wenig.

Ich verstehe zwar nicht, warum ein Array zwangsweise im Flash abgelegt 
werden soll, obwohl es nicht genutzt wird.... aber egal, ich muss nicht 
alles verstehen.

Wie Du den Compiler zwingst, das Array anzulegen? Indem Du drauf 
zugreifst.

von Oliver (Gast)


Lesenswert?

Peder schrieb:
> Es scheint
> reproduzierbar zu sein, dass immer nur das Array eingebunden wird, was
> später auch gebraucht wird.

Je nun, bei eingeschalteter Optimierung wäre es schon ein massiver Bug 
im Compiler, wenn der das anders machen würde.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Peder schrieb:

> Zum Thema "Dazulinken"
> Wenn das das gleiche ist wie "Add existing item" im Solution Explorer,
> dann führt das zu Problemen. Denn auf einmal will er in den
> dazugelinkten Dateien auch noch Headerdateien eingebungen haben.


Nein, nicht auf einmal.

Du schreibst jetzt 100 mal:

Jedes einzelne C-File wird für sich alleine kompiliert und muss daher in 
sich vollständig sein.

> Auch
> wenn die in der main-Datei schon drin sind.

INteressiert keinen, wenn die Datei a.c compiliert wird.
Wenn der Compiler a.c compiliert, dann compiliert er auch nur a.c. Was 
immer in main.c drinnen steht, ist beim compilieren von a.c vollkommen 
uninteressant.

> ... dann führt das zu Problemen.
Für Millionen von C-Programmierern weltweit ist das überhaupt kein 
Problem. Ganz im Gegenteil wäre das anders rum ein Problem.
Das Projekt, in dem ich gerade eingebunden bin komplett zu compilieren, 
dauert momentan rund 3 Stunden. Für ernsthafte Projekte ist es wichtig, 
dass jede C-Datei für sich alleine compiliert werden kann. Denn damit 
kann ich nach 2 Minuten den nächsten Programmtest nach einer Änderung 
fahren.
Allerdings sind das bei mir auch ein paar hundert C-Files (eigentlich 
sind es ja C++ Files) mehr und ein paar hundertausend Lines of Code mehr 
als bei dir.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
> Wie Du den Compiler zwingst, das Array anzulegen? Indem Du drauf
> zugreifst.

Oder per „__attribute__((used))“.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Frank M. schrieb:
>> Wie Du den Compiler zwingst, das Array anzulegen? Indem Du drauf
>> zugreifst.
>
> Oder per „__attribute__((used))“.

Das hilft aber nicht, wenn vie Variable nicht verwendet wird und der 
Linker sie rauswirft, etwa mit --gc-sections und -fdata-sections.  Bei 
neueren avr-gcc wirkt -fdata-sections nämlich auch auf PROGMEM-Daten, 
was früher[tm] nicht so war.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. schrieb:
> etwa mit --gc-sections und -fdata-sections.

Das ist dann ein Fall von "selbst schuld". ;-)

Ich kann ja noch -ffunction-sections zur Not verstehen (wenngleich ich
nach wie vor der Meinung bin, dass man eigentlich keine Funktionen in
seinem Code stehen haben sollte, die gar nicht benötigt werden), aber
-fdata-sections sollte man wohl wirklich nur angeben, wenn man das
aus irgendeinem Grunde unbedingt braucht.

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
Noch kein Account? Hier anmelden.