Arduino Sloeber - C Code einbinden

OP (Firma: Verein: BLS-Electronics) #5224680
Lesenswert?

Hallo zusammen

Ich habe mir sloeber heruntergeladen und das Paket für den ESP8266 
installiert. Soweit so gut.

Nun versuche ich, elm chans FatFS zu integrieren.
Leider bekomme ich immer Meldungen wie:
1
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_ioctl'

Die Funktionen sind aber vorhanden und Eclipse kennt sie auch 
(CTRL+Click) zudem habe ich die ordner zu den IncludePfaden hinzugefügt.

Nach etwas google hab ich dies gefunden:

https://github.com/Sloeber/arduino-eclipse-plugin/issues/579

Nun verstehe ich dies so, dass ich all meinen C-Code in das .ino file 
inkludieren müsste.
Für mich nicht machbar.

Gibt es noch andere Möglichkeiten? Das .c file in .cpp umbenennen?

Danke schonmal
Persönliche Seite #5224684
Lesenswert?

Das ist eine Linker-Fehlermeldung.

Wenn die Funktion vorhanden ist, dann wird das am name mangling 
liegen, d.h. Deine in einem C++-Modul implementierte Funktion heißt für 
den Linker anders als sie hieße, wenn sie in einem C-Modul implementiert 
worden wäre.

Die Definition (d.h. Implementierung) der Funktion muss aber mit 
C-Linkage erfolgen, also in "extern C" verpacken.
Persönliche Seite #5224950
Lesenswert?

Rufus Τ. F. schrieb:
> Die Definition (d.h. Implementierung) der Funktion muss aber mit
> C-Linkage erfolgen, also in "extern C" verpacken.

Die Definition erfolgt ja mit C-Linkage, da sie in einem C-Modul 
implementiert sind.

Das extern "C" gehört an die im C++ Teil verwendeten Deklarationen 
also
1
extern "C"  void disk_ioctl ();

Falls die Funktion auf C-Ebene als void disk_ioctl (void) implementiert 
ist.  Ditto für globale Daten.  Oder in einen extern "C" {} packen.
Persönliche Seite #5224971
Lesenswert?

Johann L. schrieb:
> Die Definition erfolgt ja mit C-Linkage, da sie in einem C-Modul
> implementiert sind.

Ja, das ist soweit klar. Wenn aber ein C-Modul auf ein Symbol in einem 
C++-Modul zugreifen soll, ist es nötig, dieses Symbol mit C-Linkage zu 
erzeugen.

Die eingangs genannte Fehlermeldung
1
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_ioctl'

lässt darauf schließen, daß hier ein C-Modul (ff.c) auf ein Symbol 
namens "disk_ioctl" zugreifen will, und das wiederum ließ mich vermuten, 
daß das in C++-Code steckt, was auch eine *.ino-Datei sein kann.
OP (Firma: Verein: BLS-Electronics) #5225170
Lesenswert?

Johann L. schrieb:
> Das extern "C" gehört an die im C++ Teil verwendeten Deklarationen
> also

hmmm... Wie muss ich das verstehen?

die ff.h enthält die C-Deklarationen der ff.c
in der ff.c wird die diskio.h inkludiert welche die C-Deklarationen der 
diskio.c enthält.

Die Fehlermeldung bezieht sich auf eine Funktion welche sich in diskio.c 
befindet (dies war der erste fehlert. Die darauffolgenden melden einfach 
andere Funktionen innerhalb der diskio.c)

die ff.h habe ich per #include in die testESP.ino inkludiert.

Wo würdet ihr also die extern "C" {} machen?

Rufus Τ. F. schrieb:
> Wenn aber ein C-Modul auf ein Symbol in einem
> C++-Modul zugreifen soll, ist es nötig, dieses Symbol mit C-Linkage zu
> erzeugen.

Da die ff.c ein reines C-Modul ist und die ff.c auf die diskctl in 
diskio.c zugreiffen möchte, sehe ich das Problem nicht ganz.
Denn eigentlich sind ja beides reine C-Module.

Ich rufe in der testESP.ino noch eine Funktion aus der ff.h auf.
Müsste ich evtl. die ff.h in extern "C" {} packen?
OP (Firma: Verein: BLS-Electronics) #5225594
Lesenswert?

Danke für deine Antwort.

Rufus Τ. F. schrieb:
> Dann scheint die diskio.c nicht zu Deinem Projekt hinzugefügt worden zu
> sein.

Eclipse kennt die diskio.c aber.
Den fs ordner habe ich auch in den include paths hinzugefügt.


Hier die gesamten Fehlermeldungen.
1
"C:\\sloeber\\arduinoPlugin\\tools\\make\\make" all 
2
'Starting combiner'
3
"C:\sloeber\/arduinoPlugin/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-gcc" -g -Wall -Wextra -Os -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static "-LC:\sloeber\/arduinoPlugin/packages/esp8266/hardware/esp8266/2.3.0/tools/sdk/lib" "-LC:\sloeber\/arduinoPlugin/packages/esp8266/hardware/esp8266/2.3.0/tools/sdk/ld" "-Teagle.flash.4m.ld" -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,register_chipv6_phy -o "sloeber-workspace/testESP/Release/testESP.elf" -Wl,--start-group    .\sloeber.ino.cpp.o  .\libraries\arduinoWebSockets-master\src\libsha1\libsha1.c.o  .\libraries\arduinoWebSockets-master\src\libb64\cdecode.c.o .\libraries\arduinoWebSockets-master\src\libb64\cencode.c.o  .\libraries\arduinoWebSockets-master\src\WebSockets.cpp.o .\libraries\arduinoWebSockets-master\src\WebSocketsClient.cpp.o .\libraries\arduinoWebSockets-master\src\WebSocketsServer.cpp.o  .\libraries\SPI\SPI.cpp.o  .\libraries\Hash\src\sha1\sha1.c.o  .\libraries\Hash\src\Hash.cpp.o  .\libraries\ESP8266mDNS\ESP8266mDNS.cpp.o  .\libraries\ESP8266WiFi\src\ESP8266WiFi.cpp.o .\libraries\ESP8266WiFi\src\ESP8266WiFiAP.cpp.o .\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp.o .\libraries\ESP8266WiFi\src\ESP8266WiFiMulti.cpp.o .\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp.o .\libraries\ESP8266WiFi\src\ESP8266WiFiScan.cpp.o .\libraries\ESP8266WiFi\src\WiFiClient.cpp.o .\libraries\ESP8266WiFi\src\WiFiClientSecure.cpp.o .\libraries\ESP8266WiFi\src\WiFiServer.cpp.o .\libraries\ESP8266WiFi\src\WiFiUdp.cpp.o  .\libraries\ArduinoOTA\ArduinoOTA.cpp.o  .\fs\diskio.c.o .\fs\ff.c.o .\fs\ffsystem.c.o .\fs\ffunicode.c.o .\fs\flash.cpp.o   "sloeber-workspace/testESP/Release/arduino.ar" -lm -lgcc -lhal -lphy -lpp -lnet80211 -lwpa -lcrypto -lmain -lwps -laxtls -lsmartconfig -lmesh -lwpa2 -llwip_gcc -lstdc++ -Wl,--end-group "-LC:sloeber-workspace/testESP/Release" sloeber-workspace/testESP/Release/arduino.ar
4
.\fs\ff.c.o:(.text.f_mkfs+0x3c): undefined reference to `disk_ioctl'
5
.\fs\ff.c.o:(.text.f_mkfs+0x44): undefined reference to `get_fattime'
6
.\fs\ff.c.o:(.text.f_mkfs+0x48): undefined reference to `disk_write'
7
.\fs\ff.c.o:(.text.f_mkfs+0xa4): undefined reference to `disk_ioctl'
8
.\fs\ff.c.o: In function `f_mkfs':
9
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_ioctl'
10
.\fs\ff.c.o: In function `mem_cpy':
11
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `get_fattime'
12
.\fs\ff.c.o: In function `st_word':
13
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `get_fattime'
14
.\fs\ff.c.o: In function `f_mkfs':
15
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_write'
16
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_write'
17
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_write'
18
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_write'
19
.\fs\ff.c.o: In function `st_dword':
20
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_write'
21
.\fs\ff.c.o:sloeber-workspace\testESP\Release/..\fs/ff.c:3476: more undefined references to `disk_write' follow
22
.\fs\ff.c.o: In function `f_mkfs':
23
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_ioctl'
24
sloeber-workspace\testESP\Release/..\fs/ff.c:3476: undefined reference to `disk_write'
25
.\fs\diskio.c.o:(.text.disk_initialize+0x0): undefined reference to `init_flash'
26
.\fs\diskio.c.o: In function `disk_initialize':
27
sloeber-workspace\testESP\Release/..\fs/diskio.c:48: undefined reference to `init_flash'
28
collect2.exe: error: ld returned 1 exit status
29
makefile:92: recipe for target 'testESP.elf' failed
30
make: *** [testESP.elf] Error 1
Persönliche Seite #5225648
Lesenswert?

Das sind die Meldungen des Linkeraufrufs.
Dem wird diskio.c.o als zu linkende Datei übergeben, wie auch etliche 
andere Dateien, insofern scheint das auch korrekt zu sein.

Den Compileraufruf sehe ich nicht. Erstaunlicherweise werden auch 
Symbole bemäkelt, die in diskio.c verwendet werden, wie man am Schluss 
erkennen kann.

Irgendwie scheint dieses Buildsystem ... merkwürdig zu sein.

Zeig mal die im Moment von Dir verwendeten Sourcen, d.h. insbesondere 
Deine diskio.c
OP (Firma: Verein: BLS-Electronics) #5225675
Lesenswert?

Rufus Τ. F. schrieb:
> Zeig mal die im Moment von Dir verwendeten Sourcen, d.h. insbesondere
> Deine diskio.c


Gerne.
Anbei die verschiedenen Sourcen.

Rufus Τ. F. schrieb:
> Irgendwie scheint dieses Buildsystem ... merkwürdig zu sein.

Das habe ich leider bei dem "sloeber" system auch schon bemerkt.
Wollte dem ganzen aber nochmals eine Chance geben, da ich gerne etwas 
umfangreicher mit dem ESP8266 auf Arduinobasis arbeiten würde.

Da hätte ich gerne eine IDE wie Eclipse oder ähnliches gehabt.
Deshalb sloeber.
Angehängte Dateien:
Persönliche Seite #5225719
Lesenswert?

Rolf M. schrieb:
> Ändere mal die Reihenfolge beim Linken, also erst ff und dann diskio.

Das ist ziemlich sicher nicht die Ursache des Problems. Das Ändern der 
Reihenfolge ist nur bei Verwendung von "weak symbols" relevant, die aber 
nur beim Einsatz von Libraries (*.a) eine Bedeutung haben.

Zu "diskio.c"

Wo wird _USE_IOCTL definiert?

Wenn das nicht definiert ist, gibt es die Funktion disk_ioctl nicht.
OP (Firma: Verein: BLS-Electronics) #5225744
Lesenswert?

Ja, das war jenes problem.

Nun habe ich nur noch ein Problem.
in der diskio.c wird auf eine funktion der flash.cpp zugegriffen.
Da die flash.cpp ja eine C++ Datei ist, scheint es so als ob ich nicht 
von der C-Funktion auf diese vermeintliche C++ funktion zugreifen kann.

Kommmt hier nun das extern "C" {} ins spiel?

EDIT:

Wenn ich
1
extern "C"
2
{
in der flash.h am Anfang platziere und unten die Klammer schliesse, 
bekomme ich den Fehler:
1
..\fs\flash.h:14:8: error: expected identifier or '(' before string constant
Persönliche Seite #5225776
Lesenswert?

Patrik S. schrieb:
> Kommmt hier nun das extern "C" {} ins spiel?

So ist es.


> Wenn ich ...

Du musst das "extern C" in der Headerdatei wiederum in einem 
#ifdef-Block verpacken:
1
#ifdef __cplusplus
2
extern "C" {
3
#endif
4

5
...
6
...
7
...
8

9
#ifdef __cplusplus
10
}
11
#endif

Das muss in der Headerdatei geschehen, damit diese sowohl aus dem 
Kontext eines C-Moduls als auch aus dem Kontext eines C++-Moduls 
verstanden wird.

Nötig ist das nur bei den Symbolen, die für das C-Modul von Interesse 
sind; Du kannst also die restlichen C++-Deklarationen auch vor dem 
C-Modul verstecken.

Die Funktion(en), die aus C heraus aufgerufen werden sollen, müssen auch 
im Code mit "extern C" gekapselt werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren