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):
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
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
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.
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.
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
conststaticuint8_tflash_table_low[]PROGMEM=
3
{
4
#include"ProgammLow.inc"
5
};
6
7
conststaticuint8_tflash_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.
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.
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
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...
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.
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.
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
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.
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.
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.