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!
Hi,
du hast das so definiert:
Im File1.c ist definiert:
static uint8_t strgCode[50] ={ 55,..... }
Static bedeutet für den Linker, linken aus anderen Modulen nicht
erlaubt.
Also, "static" und "extern" widersprechen sich.
Gruß
Olaf
Olaf D. schrieb:> Also, "static" und "extern" widersprechen sich.
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!
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.
Hi Rudi,
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.
Gruß
Olaf
Rudi schrieb:>> Also, "static" und "extern" widersprechen sich.> 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.
Hier und an anderen Stellen finde ich immer nur diese Erklärung:
https://stackoverflow.com/questions/4576607/what-does-static-mean-in-ansi-c
Rudi schrieb:> Ich will diese> Daten, weil sie nicht geändert werden, einfach im Flash haben. Wenn das> anders programmiert werden kann, dann tue ich es.
Hat genau dafür der Liebe Gott nicht den Qualifier "const" erschaffen?
Grüßle,
Volker
Es gibt im Pico SDK eine Header Datei:
src/rp2_common/pico_platform/include/pico/platform.h
Dort befindet sich ein:
#define __in_flash(group) __attribute__((section(".flashdata." group)))
Olaf D. schrieb:> 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.
Rudi schrieb:> Ich will diese Daten, weil sie nicht geändert werden, einfach im Flash> haben.
Das scheint ein Mißverständnis zu sein. Das Schlüsselwort static hat mit
Flash versus RAM nichts zu tun.
LG, Sebastian
Volker B. schrieb:> Hat genau dafür der Liebe Gott nicht den Qualifier "const" erschaffen?
Hallo, danke, das war's. Aber warum hat mir Gott das nicht selbst
erklärt?
Zumindest linkt es nun. Austesten fängt jetzt an und dauert noch.
Gruß Rudi
Rudi schrieb:> Volker B. schrieb:>> Hat genau dafür der Liebe Gott nicht den Qualifier "const" erschaffen?>> Hallo, danke, das war's. Aber warum hat mir Gott das nicht selbst> erklärt?> Zumindest linkt es nun. Austesten fängt jetzt an und dauert noch.>> Gruß Rudi
Dennoch liegt's noch im RAM. Abhilfe:
Beitrag "Re: Linker-Fehlermeldung unklar"
Norbert schrieb:> #define __in_flash(group) __attribute__((section(".flashdata." group)))
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?
Rudi schrieb:> 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.
Niklas G. schrieb:> 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.
*) nicht im "Arduino"-Sinne
Harald K. schrieb:> 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.
Niklas G. schrieb:> Das hat aber nichts mit der anderen Bedeutung von "static" zu tun
Was könnte ich nur mit "der einen Bedeutung" und "der anderen Bedeutung"
gemeint haben?
Harald K. schrieb:> Was könnte ich nur mit "der einen Bedeutung" und "der anderen Bedeutung"> gemeint haben?
Dass es sich bei "static" um ein Homonym handelt...
Die selbe Bezeichnung für unterschiedliche Dinge.
Rahul D. schrieb:> Die selbe Bezeichnung für unterschiedliche Dinge.
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.
Rahul D. schrieb:> Harald K. schrieb:>> Was könnte ich nur mit "der einen Bedeutung" und "der anderen Bedeutung">> gemeint haben?>> Dass es sich bei "static" um ein Homonym handelt...> Die selbe Bezeichnung für unterschiedliche Dinge.
Was ist eigentlich eine rhetorische Frage?
Axel S. schrieb:> Was ist eigentlich eine rhetorische Frage?
Eine, auf die man keine Antwort erwartet.
Es ist aber auch nicht verboten, darauf zu "antworten".
>> 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?
Rudi schrieb:> 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
----------------------------------------------------------------
Grüßle,
Volker
Norbert schrieb:> Rudi schrieb:>> Hallo, ich warte noch immer auf ne Erklärung,>> 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.
Rudi schrieb:> 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.
Norbert schrieb:> 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.