Hallo
Mein Programm soll für PiPico in C mit VsCode gebaut werden.
Es besteht aus 9 .c/.h Files. Compilieren einzelner Module ist fehlerfrei. Beim erzeugen des Gesmtprojektes kommt die Fehlermeldung:
while(i<16)if(lst[i++]==(int8_t)e)f=true;// ist eingabe in Liste
55
if(f==false)e=-1;
56
}
57
RedLed_AB(0,false);
58
returne;<<<----diesistZeile101
59
}
60
}
61
sleep_us(LoopTime);
62
}
63
}
Ich finde in Getnum() keinen Fehler, aber ohne diese Funktion läuft der Compiller durch. Und wieso auf Zeile 101, da ist doch kein strgCode. Und wo soll der Unterschied zu readint() sein?
Schätze, ich steh auf'n Schlauch!
Das wundert mich aber. Denn ich habe noch einige static Daten mehr im Projekt, die ich auf die gleiche Weise gebrauche und mit denen allen funktioniert alles problemlos.
Und zur Beachtung: in Funktion readint() funtioniert es, obwohl im selben File!
int main(int argc, char ** argv)
{
for(int i = 0; i < 50; i++)
{
printf("strgCode(%i)=%i\n", i, strgCode[i]);
}
}
olaf@nb04 ~/tmp/c $ gcc -o test file1.c file2.c
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/cc4PGPoJ.o: warning: relocation against strgCode' in read-only section .text'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/cc4PGPoJ.o: in function main': file2.c:(.text+0x24): undefined reference to strgCode'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: Fehler: ld gab 1 als Ende-Status zurück
olaf@nb04 ~/tmp/c $
olaf@nb04 ~/tmp/c $
olaf@nb04 ~/tmp/c $ vi file1.c (remove static keyword)
olaf@nb04 ~/tmp/c $ cat file1.c
#include <stdint.h>
Ja, ok. Vieleicht liegt weil dur für einen PC compiliert hast. Der hat sein Programm im RAM und nicht im Flash, wie beim PiPico. Ich will diese Daten, weil sie nicht geändert werden, einfach im Flash haben. Wenn das anders programmiert werden kann, dann tue ich es.
für welche Plattform du das compilierst ist erstmal egal.
Der Linker muss die Adresse der Variablen auflösen.
Wenn du ihm verbietest von einem File auf das andere zuzugreifen,
kann er das nicht durchführen.
Ob diese Variable im (nur) im Flash landet hängt in erste Linie
von der Architektur, der Variablen-Definition und dem Linker-Script ab.
Dort kannst du alle Variablen erfassen, die nur im Flash stehen sollen.
Bei dem Pico kann ich leider nicht weiterhelfen.
Aber der Linker-Fehler sollte nach entfernen von "static" weg sein.
Das wundert mich aber. Denn ich habe noch einige static Daten mehr im
Projekt, die ich auf die gleiche Weise gebrauche und mit denen allen
funktioniert alles problemlos.
Da wir nicht deine komplette Source-Dateien haben, wundern wir uns zunächst auch nicht.
Was bedeutet überhaupt "problemlos"? Das Programm läuft doch mit dem Linker-Fehler gar nicht, oder?
Zumindest ist es denkbar, dass der Linker das Problem mit der undefinierten Variable 'strgCode' nur einmal und nicht mehrfach meldet. Das könnte erklären, warum es in 'readint()' nicht auftritt.
Der Linker muss die Adresse der Variablen auflösen.
Richtig.
Wenn du ihm verbietest von einem File auf das andere zuzugreifen,
kann er das nicht durchführen.
Es wird ihm nicht verboten.
Das Compilat der Datei mit dem 'static' enthält einfach gar keine Link-Information für den betreffenden Namen, also weiß der Linker nicht, dass es diesen Namen gibt.
Dann schmeiß mir doch nicht nur diesen Brocken hin. Ich seh' schon das könnte was bewirken. Aber wie ich sowas anwende, da hab ich zuwenig Erfahrung. Also konkrete Frage: wie baue ich das in mein Projekt ein?
Das wundert mich aber. Denn ich habe noch einige static Daten mehr im
Projekt, die ich auf die gleiche Weise gebrauche und mit denen allen
funktioniert alles problemlos
Kann nicht sein. Hast du vielleicht die static Variable im Header definiert sodass sie dann letztendlich mehrfach im Executable auftaucht?
Der SINN von "static" ist es schließlich, dass man die Variable eben NICHT aus anderen Dateien nutzen kann - da ist es kein Wunder, dass es hier nicht geht, aber sehr verwunderlich, wenn es an anderer Stelle doch geht.
Der SINN von "static" ist es schließlich, dass man die Variable eben
NICHT aus anderen Dateien nutzen kann
Der Vollständigkeit halber:
Das ist die eine der Bedeutungen von /static/, die Sichtbarkeit von Symbolen für den Linker.
Für jede /translation unit/ (plump: jedes übersetzte Sourcefile) legt der Compiler zwei Listen von Symbolnamen an, die der Linker verarbeitet. Die eine führt alle von der /translation unit/ exportierten Symbolnamen auf (d.h. alle enthaltenen Funktionen und Variablen, auf die von "außen" zugegriffen werden kann), und die andere führt alle /importierten/ Symbolnamen auf, d.h. Funktonen und Variablen, die anderswo definiert sind, auf die die /translation unit/ aber zugreift.
Der Linker ist bestrebt, alle /importierten/ Symbolnamen aufzulösen, gelingt ihm das nicht anhand der verschiedenen /translation units/, greift er auf etwaige ihm angegebene Libraries* zurück. So funktioniert z.B. der Aufruf von Funktionen wie /printf/.
Die andere Bedeutung von /static/ gibt es bei der Definition von Variablen /innerhalb/ einer Funktion. Da behält die Variable ihren Wert auch nach Verlassen der Funktion, so daß sie beim näächsten Aufruf der funktion weiterverwendet werden kann. Die Initialisierung der Variablen erfolgt nur einmal, auch wenn sie im Funktionsrumpf untergebracht ist.
Die andere Bedeutung von /static/ gibt es bei der Definition von
Variablen /innerhalb/ einer Funktion.
Das hat aber nichts mit der anderen Bedeutung von "static" zu tun, das Keyword wird hier nur recycelt. Die in C++ hinzugekommene Bedeutung von "static" bei Klassen-Membern ist ebenfalls davon unabhängig.
Da hätten K&R besser ein weiteres Keyword "intern" spendiert, das dann als Gegenpart zu "extern" fungierte und auch die Nicht-Sichtbarkeit besser benannt hätte. Ich weiß, Konjunktiv und Fahrradkette :)
Hallo, jetzt ist mir die Bedeutung von noch Group unklar. Ich hab halt mal irgentwas genommen. War ok.
Es hat bei uint8_t funktioniert. Mit der selben Group hat es auch mit char[] funktioniert.
Aber für *char[] hab ich eine anderen Groupnamen gebraucht.
In CppReference habe ich nichts gefunden.
Hallo, jetzt ist mir die Bedeutung von noch Group unklar. Ich hab halt
mal irgentwas genommen. War ok.
Es hat bei uint8_t funktioniert. Mit der selben Group hat es auch mit
char[] funktioniert.
Aber für *char[] hab ich eine anderen Groupnamen gebraucht.
In CppReference habe ich nichts gefunden.
Hallo, ich warte noch immer auf ne Erklärung, oder gibt es keine?
Hallo, ich warte noch immer auf ne Erklärung, oder gibt es keine?
google kaput?
Section attribute macro for placement in flash even in a COPY_TO_RAM binary
For example a uint32_t variable explicitly placed in flash (it will hard fault if you attempt to write it!)
uint32_t __in_flash("my_group_name") foo = 23;
The section attribute is .flashdata.<group>
group a string suffix to use in the section name to distinguish groups that can be linker garbage-collected independently
Möglicherweise nachdem sich die Manieren ein wenig verbessert haben.
Ich wuste noch nicht, dass Warten eine Maniere ist. Und wenn, dann eher eine positive. Oder ist dir das norddeutsche Sprichwort "Nun mal Butter bei die Fische" lieber?
Und die Mitteilung von Volkers google kannte ich schon längst. Diese Mitteilung erklärt aber nicht, warum verschiedene Datentypen verschiedene Groups brauchen. Und da mein google keine Erklärung dazu ausspuckt, werde ich weiterhin warten.
Ich wuste noch nicht, dass Warten eine Maniere ist.
Nein, sicher nicht. Aber dein frech forderndes Auftreten.
Im Übrigen machst du wohl etwas falsch, da eine bunte Mischung verschiedener Variablentypen im FLASH hier fehlerfrei kompiliert.
Im Übrigen machst du wohl etwas falsch, da eine bunte Mischung
verschiedener Variablentypen im FLASH hier fehlerfrei kompiliert.
Äh? Ich dachte immer ein Compiler zeigt mir meine Fehler. Wenn das so geht, dann wundert es micht nicht mehr, dass er auch Fehler zeigt, wo keine sind.
Aber es wundert mich nicht mehr: wenn die man-Page von gcc(1) 20000 Zeilen lang ist, kann sich kein Mensch mehr durchfinden. Auch wenn ich mich hier im Blindflug befinde, die letzte Programmversion lief noch.
Und das mit der "bunten Mischung" verstehe ich auch nicht. Sortierst du deine Variablentypen, wobei die hier im Flash gar nicht variabel sind.