Forum: Mikrocontroller und Digitale Elektronik Arduino Sloeber - C Code einbinden


von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Lesenswert?

Rufus Τ. F. schrieb:
> extern C

Danke.

Wo soll ich denn das extern "C"  {} platzieren?

Ich habe mehrere *.c files.
Soll ich nun das gesamte File von Anfang bis Ende einpacken?
Oder soll ich das gesamte header file einpacken?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wo sind die angekrittelten Funktionen definiert?

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Angehängte Dateien:

Lesenswert?

Rufus Τ. F. schrieb:
> Wo sind die angekrittelten Funktionen definiert?

Die sind hauptsächlich in den files von elm-chan
Siehe Anhang.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was bedeutet das "x" im Project Explorer?

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Lesenswert?

Rufus Τ. F. schrieb:
> Was bedeutet das "x" im Project Explorer?

Das bedeutet dass es dort errors gab.
Der erste Error ist jener, welchen ich oben gepostet habe.

von Johann L. (gjlayde) Benutzerseite


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.

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


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?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann scheint die diskio.c nicht zu Deinem Projekt hinzugefügt worden zu 
sein.

Naja, oder wie Dein Screenshot verrät, ließ sie sich nicht korrekt 
übersetzen.

Interessant wäre jetzt natürlich die /Compiler/-Fehlermeldung, die beim 
Übersetzen von diskio.c ausgegeben wird.

Die Linkerfehlermeldungen sind erst später relevant.

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


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

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


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

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Angehängte Dateien:

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.

von Rolf M. (rmagnus)


Lesenswert?

Ändere mal die Reihenfolge beim Linken, also erst ff und dann diskio.

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Lesenswert?

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

hmmm.... weist du wie ich das bei eclipse hinkriege?

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Angehängte Dateien:

Lesenswert?

So, habe mal den gesamten Build-Log angehängt.
Dieser Prozess dauert ganze 6 Minuten. Warum das so langsam ist weiss 
ich auch nicht.

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Lesenswert?

Rufus Τ. F. schrieb:
> Zu "diskio.c"
>
> Wo wird _USE_IOCTL definiert?

Sehr gute Frage...

Habe dies nun definiert und lasse den Build nochmals laufen.
Wäre natürlich super, wenns nur das war. Andererseits auch schade um die 
vielen Zeit, wegen nur einem define.

von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


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

: Bearbeitet durch User
von Patrik S. (Firma: Verein: BLS-Electronics) (patrikseiler)


Lesenswert?

Problem gelöst.

Habe in der flash.cpp

bei #include flash.h

das extern c angefügt.

sieht nun so aus:
1
extern "C" {
2
#include flash.h
3
}

Danke für eure mithilfe!

von Rufus Τ. F. (rufus) Benutzerseite


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.

: Bearbeitet durch User
von Harry L. (mysth)


Lesenswert?

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

Für mich klingt das, als wenn die zugehörigen C-Files gar nicht 
compiliert werden, was nicht verwunderlich wäre, wenn die im 
Include-PATH liegen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Harry L. schrieb:
> Für mich klingt das, als wenn die zugehörigen C-Files gar nicht
> compiliert werden,

Sie werden compiliert, sieh Dir den weiter oben geposteten Linkeraufruf 
an. Würden sie nicht compiliert, aber dem Linker übergeben werden, würde 
der Linker entsprechend motzen, daß er Dateien und nicht Symbole nicht 
finden kann.

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.