Forum: Compiler & IDEs ESP8266 C++11 features wie lambdas


von Max M. (maxmicr)


Lesenswert?

Um meinen Code etwas modularer zu gestalten, wollte ich aus Spaß an der 
Freude auf C++11 Features zurückgreifen (der Compiler lässt sich 
problemlos mit *-std=c++11* aufrufen).

Ich hab eine einfache Klasse mit statischen Methoden, eine davon liefert 
das größte bzw. kleinste Element eines Arrays zurück. Das habe ich 
aktuell so gelöst:
1
int32_t ICACHE_FLASH_ATTR Util::get_lowest_value(int32_t *values) {
2
  return Util::get_value_with_compare(values, [](int32_t v1, int32_t v2) -> bool { return v1 < v2; });
3
}
4
5
int32_t ICACHE_FLASH_ATTR Util::get_highest_value(int32_t *values) {
6
  return Util::get_value_with_compare(values, [](int32_t v1, int32_t v2) -> bool { return v1 > v2; });
7
}
8
9
int32_t Util::get_value_with_compare(int32_t *values, std::function<bool (int32_t, int32_t)> compare) {
10
  int32_t value = values[0];
11
  for(uint16_t i = 1; i < sizeof(values); i++) {
12
    if(compare(values[i], value))
13
      value = values[i];
14
  }
15
16
  return value;
17
}

wobei get_value_with_compare eine private Methode der Klasse Util ist, 
nur get_highest_value  und get_lowest_value sind öffentlich 
aufrufbar.

Ich weiß nicht, ob man sich mit dem Namespace std irgendwelchen großen 
Dateien dazuholt, aber nun bekomme ich die Meldung:
1
xtensa-lx106-elf-gcc  -L../lib -nostdlib -T../ld/eagle.app.v6.ld -Wl,--no-check-sections -Wl,--gc-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -lm -llwip -lwpa -lcrypto -lmain -ljson -lupgrade -lmbedtls -lpwm -ldriver -lsmartconfig user/.output/eagle/debug/lib/user.a BMP280/.output/eagle/debug/lib/BMP280.a Soft_I2C/.output/eagle/debug/lib/I2C.a SSD1306_OLED/.output/eagle/debug/lib/OLED.a WIFI/.output/eagle/debug/lib/WIFI.a Util/.output/eagle/debug/lib/Util.a Buffer/.output/eagle/debug/lib/Buffer.a -Wl,--end-group -o .output/eagle/debug/image/eagle.app.v6.out
1
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: .output/eagle/debug/image/eagle.app.v6.out section `.text' will not fit in region `iram1_0_seg'

In der Headerdatei hab ich außerdem dieses include:
1
#include <functional>
.

Hat jemand Erfahrung damit?

Edit: Ich hatte das zuvor mit Funktionspointer anstatt lambdas gelöst, 
da hat es einwandfrei kompiliert.

Edit_2: Mir fällt gerade auf, dass es sich hier um einen Linker-Error 
handelt, d.h. der Compiler hat schon alles erfolgreich kompiliert.

: Bearbeitet durch User
von Sven P. (Gast)


Lesenswert?

Max M. schrieb:
> `.text' will not fit in region `iram1_0_seg'

Der Linker will .text ins RAM packen?

von Max M. (maxmicr)


Lesenswert?

Sven P. schrieb:
> Der Linker will .text ins RAM packen?

Das ist glaub ich eine Methode des ESP8266 um bestimmten Code schneller 
ausführen zu können da der Flash nur über SPI angebunden und 
entsprechend langsam ist. Ich hab aber alle Methoden mit 
ICACHE_FLASH_ATTR markiert, d.h. ich erwarte, dass die ins Flash und 
nicht in den internen RAM gepackt werden.
Der Compiler verwendet bereits das Optimierungsflag -Os, kleiner 
bekomme ich es also nicht mehr.

Ich vermute, dass man sich mit *#include<functional>* zu viel Zeug dazu 
holt?

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Max M. schrieb:
> Ich vermute, dass man sich mit *#include<functional>* zu viel Zeug dazu
> holt?

Du verwendest nichts aus dem functional header. Demnach benötigt das 
include kein einziges Byte.

/edit
Ah doch, das std::function hab ich nicht gesehn. Aber trotzdem nein. 
<functional> ist im Prinzip zero-cost. std::function hat auf Grund der 
internen Type-Erasure natürlich etwas overhead, aber das beläuft sich 
auf ein paar Byte...

/edit2
proof: https://godbolt.org/z/gbDLeR
Der is zwar für ARM, zeigt aber dass der Mehraufwand wirklich gering 
ist.

: Bearbeitet durch User
von Max M. (maxmicr)


Lesenswert?

Danke dir, Vincent.

Jetzt steht ich nur vor dem Problem nicht zu wissen, an was es sonst 
noch liegen könnte :(

von Markus F. (mfro)


Lesenswert?

Max M. schrieb:
> Danke dir, Vincent.
>
> Jetzt steht ich nur vor dem Problem nicht zu wissen, an was es sonst
> noch liegen könnte :(

Nachdem der Linker explizit mit

> `.text' will not fit in region `iram1_0_seg'

meckert, scheint "ICACHE_FLASH_ATTR" wohl nicht so funktioniert zu 
haben, wie Du dir das gedacht hast?

Was sagt das mapfile?

von Max M. (maxmicr)


Lesenswert?

Markus F. schrieb:
> Was sagt das mapfile?

Ich kenne das von meinen AVR-GCC Projekten, in dem man den Linker 
explizit ein map-File mit angibt (zusätzlich zu den ganzen 
Object-Files).

Hier sehe ich im Linker-Aufruf (siehe erster Beitrag) keine Angabe eines 
mapfiles. Im Projektordner, in dem die Sourcen und Object-Files liegen, 
finde ich auch nichts.

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Max M. schrieb:
> Hier sehe ich im Linker-Aufruf (siehe erster Beitrag) keine Angabe eines
> mapfiles.

Dann schreib' doch eins hin?

Im map File sagt einem der Linker ausführlich (wenn man ihn - mit 
"-Wl,-Map -Wl,"mapfile" dazu auffordert), was er wohin getan hat.

Und das interessiert dich doch eigentlich, oder?

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Markus F. schrieb:
> Und das interessiert dich doch eigentlich, oder?

Achso, jetzt verstehe ich - danke!

Hast du eine Idee, wonach ich da suchen soll? Ist ehrlich gesagt das 
erste mal, dass ich mir so eine Mapdatei ansehe.

von Vincent H. (vinci)


Lesenswert?

Max M. schrieb:
> Das ist glaub ich eine Methode des ESP8266 um bestimmten Code schneller
> ausführen zu können da der Flash nur über SPI angebunden und
> entsprechend langsam ist. Ich hab aber alle Methoden mit
> ICACHE_FLASH_ATTR markiert, d.h. ich erwarte, dass die ins Flash und
> nicht in den internen RAM gepackt werden.

Ich kenn mich mit dem ESP8266 leider nicht aus, aber eine kurze Google 
Suche ergab das hier
https://www.esp8266.com/viewtopic.php?f=159&t=11966


Check mal ob das Macro an der Stelle wo du es nutzt überhaupt richtig 
definiert ist oder re-define es testweise(!!!) in der entsprechenden 
Source-Datei mal kurz neu.

von Max M. (maxmicr)


Lesenswert?

Anbei nochmal die komplette Ausgabe auf der Konsole:
1
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: .output/eagle/debug/image/eagle.app.v6.out section `.text' will not fit in region `iram1_0_seg'
2
Util/.output/eagle/debug/lib/Util.a(Util.o):(.text._ZNSt14_Function_base13_Base_managerIZN4Util16get_lowest_valueEPKiEUliiE_E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation+0x4): undefined reference to `operator new(unsigned int)'
3
Util/.output/eagle/debug/lib/Util.a(Util.o):(.text._ZNSt14_Function_base13_Base_managerIZN4Util16get_lowest_valueEPKiEUliiE_E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation+0x8): undefined reference to `operator delete(void*)'
4
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_clone':
5
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1910: undefined reference to `operator new(unsigned int)'
6
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_destroy':
7
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1926: undefined reference to `operator delete(void*)'
8
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_get_pointer':
9
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1893: undefined reference to `operator new(unsigned int)'
10
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_clone':
11
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1910: undefined reference to `operator delete(void*)'
12
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `Util::printFloat(float, char*)':
13
/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266/Util/Util.cpp:13: undefined reference to `std::__throw_bad_function_call()'
14
/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266/Util/Util.cpp:18: undefined reference to `std::__throw_bad_function_call()'
15
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `std::function<bool (int, int)>::operator()(int, int) const':
16
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:2464: undefined reference to `operator new(unsigned int)'
17
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `Util::get_value_with_compare(int const*, std::function<bool (int, int)>)':
18
/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266/Util/Util.cpp:36: undefined reference to `operator new(unsigned int)'
19
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `~function':
20
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:2174: undefined reference to `operator new(unsigned int)'
21
Util/.output/eagle/debug/lib/Util.a(Util.o):(.rodata._ZTIZN4Util17get_highest_valueEPKiEUliiE_+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
22
Util/.output/eagle/debug/lib/Util.a(Util.o):(.rodata._ZTIZN4Util16get_lowest_valueEPKiEUliiE_+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
23
../lib/libc.a(lib_a-abort.o):(.literal+0x0): undefined reference to `_exit'
24
../lib/libc.a(lib_a-abort.o): In function `abort':
25
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
26
../lib/libc.a(lib_a-signal.o):(.literal+0x0): undefined reference to `_malloc_r'
27
../lib/libc.a(lib_a-signal.o):(.literal+0x4): undefined reference to `_getpid_r'
28
../lib/libc.a(lib_a-signal.o):(.literal+0x8): undefined reference to `_kill_r'
29
../lib/libc.a(lib_a-signal.o): In function `_init_signal_r':
30
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/signal/signal.c:110: undefined reference to `_malloc_r'
31
../lib/libc.a(lib_a-signal.o): In function `_raise_r':
32
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/signal/signal.c:163: undefined reference to `_getpid_r'
33
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/signal/signal.c:163: undefined reference to `_kill_r'
34
collect2: error: ld returned 1 exit status
35
../Makefile:403: recipe for target '.output/eagle/debug/image/eagle.app.v6.out' failed
36
make[1]: *** [.output/eagle/debug/image/eagle.app.v6.out] Error 1
37
make[1]: Leaving directory '/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266'
38
Makefile:337: recipe for target '.subdirs' failed
39
make: *** [.subdirs] Error 2

Ich bin mir nicht sicher, ob die Meldungen nach
1
section `.text' will not fit in region `iram1_0_seg'
 auf eben diesen Fehler zurückzuführen sind, oder ob es sich um 
"eigenständige" Fehler handelt.

Vincent H. schrieb:
> Ich kenn mich mit dem ESP8266 leider nicht aus, aber eine kurze Google
> Suche ergab das hier

Danke dir für den Hinweis, wie im verlinkten Beitrag angemerkt, sollte 
ICACHE_FLASH definiert sein, dass ist in den Flags beim Kompilieren 
enthalten:
1
xtensa-lx106-elf-g++ -Os -std=c++11 -g -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections -fno-builtin-printf  -DICACHE_FLASH -DGLOBAL_DEBUG_ON -DSPI_FLASH_SIZE_MAP=4   -I include -I ../user/ -I ./ -I . -I . -I /opt/esp/sdk/include  -o .output/eagle/debug/obj/Util.o -c Util.cpp

Sicherheitshalber habe ich nun in einigen Sourcefiles
1
#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))

hinzugefügt. Leider immer noch das selbe Verhalten.

Ich vermute, dass einfach irgendwas beim Linken schief läuft, sobald 
Lambdas ins Spiel kommen. Mit Funktionspointern klappt das ja alles 
wunderbar. Zu wenig Platz ist also definitiv nicht.

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Max M. schrieb:
> Ich vermute, dass einfach irgendwas beim Linken schief läuft, sobald
> Lambdas ins Spiel kommen. Mit Funktionspointern klappt das ja alles
> wunderbar. Zu wenig Platz ist also definitiv nicht.

Lambdas sind zwar ein tolles Sprachfeature, genau genommen sind sie aber 
nur "syntactic sugar" für structs mit operator() overload. Das heißt für 
den Linker ist ein Lambda ein Methodenaufruf wie jeder andere auch und 
wenn das nicht funktionieren würde, dann wäre der Linker komplett 
kaputt. :)

Der Rest des Outputs verrät mir aber das dein eigentliches Problem (bzw. 
Probleme) ganz wo anders liegt. Zum einen siehts so aus als würdest du 
mit RTTI compilieren 
(https://en.wikipedia.org/wiki/Run-time_type_information) was via 
Compiler-Flag "-fno-rtti" abstellen lässt. Und weiters dürften da eine 
Reihe syscalls ala _exit, _malloc_r, _kill_r, usw. fehlen wobei ich 
nicht grad sicher bin ob das nicht ein Folgefehler ist...

Probier mal mit fno-rtti zu compilieren und dann schau ma weiter ;)

von Markus F. (mfro)


Lesenswert?

Vincent H. schrieb:
> Und weiters dürften da eine
> Reihe syscalls ala _exit, _malloc_r, _kill_r, usw. fehlen wobei ich
> nicht grad sicher bin ob das nicht ein Folgefehler ist...

So wie ich das sehe, meckert der Linker da bloß, weil er für das Zeug 
keinen Platz mehr hatte.

von Max M. (maxmicr)


Lesenswert?

Danke für eure Hilfe!

Vincent H. schrieb:
> Probier mal mit fno-rtti zu compilieren und dann schau ma weiter ;)

Hier die Ausgabe, es hat sich leider nicht viel getan :(
1
xtensa-lx106-elf-gcc  -L../lib -nostdlib -T../ld/eagle.app.v6.ld -Wl,--no-check-sections -Wl,--gc-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -lm -llwip -lwpa -lcrypto -lmain -ljson -lupgrade -lmbedtls -lpwm -ldriver -Wl,-Map -Wl,"mapfile.map" -Wl,--cref -lsmartconfig user/.output/eagle/debug/lib/user.a BMP280/.output/eagle/debug/lib/BMP280.a Soft_I2C/.output/eagle/debug/lib/I2C.a SSD1306_OLED/.output/eagle/debug/lib/OLED.a WIFI/.output/eagle/debug/lib/WIFI.a Util/.output/eagle/debug/lib/Util.a Buffer/.output/eagle/debug/lib/Buffer.a -Wl,--end-group -o .output/eagle/debug/image/eagle.app.v6.out
2
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: .output/eagle/debug/image/eagle.app.v6.out section `.text' will not fit in region `iram1_0_seg'
3
Util/.output/eagle/debug/lib/Util.a(Util.o):(.text._ZNSt14_Function_base13_Base_managerIZN4Util16get_lowest_valueEPKiEUliiE_E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation+0x0): undefined reference to `operator new(unsigned int)'
4
Util/.output/eagle/debug/lib/Util.a(Util.o):(.text._ZNSt14_Function_base13_Base_managerIZN4Util16get_lowest_valueEPKiEUliiE_E10_M_managerERSt9_Any_dataRKS6_St18_Manager_operation+0x4): undefined reference to `operator delete(void*)'
5
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_clone':
6
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1910: undefined reference to `operator new(unsigned int)'
7
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_destroy':
8
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1926: undefined reference to `operator delete(void*)'
9
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_get_pointer':
10
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1893: undefined reference to `operator new(unsigned int)'
11
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `_M_clone':
12
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:1910: undefined reference to `operator delete(void*)'
13
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `Util::printFloat(float, char*)':
14
/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266/Util/Util.cpp:13: undefined reference to `std::__throw_bad_function_call()'
15
/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266/Util/Util.cpp:18: undefined reference to `std::__throw_bad_function_call()'
16
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `std::function<bool (int, int)>::operator()(int, int) const':
17
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:2464: undefined reference to `operator new(unsigned int)'
18
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `Util::get_value_with_compare(int const*, std::function<bool (int, int)>)':
19
/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266/Util/Util.cpp:36: undefined reference to `operator new(unsigned int)'
20
Util/.output/eagle/debug/lib/Util.a(Util.o): In function `~function':
21
/opt/esp/crosstool-NG/builds/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional:2174: undefined reference to `operator new(unsigned int)'
22
../lib/libc.a(lib_a-abort.o):(.literal+0x0): undefined reference to `_exit'
23
../lib/libc.a(lib_a-abort.o): In function `abort':
24
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
25
../lib/libc.a(lib_a-signal.o):(.literal+0x0): undefined reference to `_malloc_r'
26
../lib/libc.a(lib_a-signal.o):(.literal+0x4): undefined reference to `_getpid_r'
27
../lib/libc.a(lib_a-signal.o):(.literal+0x8): undefined reference to `_kill_r'
28
../lib/libc.a(lib_a-signal.o): In function `_init_signal_r':
29
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/signal/signal.c:110: undefined reference to `_malloc_r'
30
../lib/libc.a(lib_a-signal.o): In function `_raise_r':
31
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/signal/signal.c:163: undefined reference to `_getpid_r'
32
/home/wjg/Repo/esp-open-sdk-20170622/crosstool-NG/.build/src/newlib-2.0.0/newlib/libc/signal/signal.c:163: undefined reference to `_kill_r'
33
collect2: error: ld returned 1 exit status
34
../Makefile:403: recipe for target '.output/eagle/debug/image/eagle.app.v6.out' failed
35
make[1]: *** [.output/eagle/debug/image/eagle.app.v6.out] Error 1
36
make[1]: Leaving directory '/mnt/c/Users/Standardbenutzer/Documents/ESP8266/Projects/ESP8266'
37
Makefile:337: recipe for target '.subdirs' failed
38
make: *** [.subdirs] Error 2

Vincent H. schrieb:
> Und weiters dürften da eine
> Reihe syscalls ala _exit, _malloc_r, _kill_r, usw. fehlen wobei ich
> nicht grad sicher bin ob das nicht ein Folgefehler ist

Soweit ich das richtig im Kopf habe, hat espressif im SDK eigene, 
äquivalente Funktionen implementiert (z.B. os_malloc anstatt malloc) 
und die normalen Funktionsnamen sind nicht verfügbar.

Vincent H. schrieb:
> dann wäre der Linker komplett
> kaputt. :)

Danke für die Erklärung, das macht natürlich Sinn.

Kann es sein, dass der Linker aufgrund der Lambda-Geschichte nun die 
ganzen C-Standardbibliothek nachlädt, deren Funktionen natürlich nicht 
das Attribute ICACHE_FLASH_ATTR aufweisen und daher in den RAM gepackt 
werden?

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Wie gesagt ist ein Lambda ein Sprachfeature und nicht Teil der 
Bibliothek.

Was aber auf jeden Fall Probleme macht ist std::function. Der 
"std::__throw_bad_function_call()" etwa ist eine Exception die von 
std::function geworfen werden kann. An der Stelle sei erwähnt dass 
"fno-exceptions" wohl auch ein sinnvolles Flag wäre...

Weiters kann std::function allozieren falls der interne Buffer für das 
Callable das man hineinspeichern will nicht ausreicht. Das verursacht 
dann vermutlich die Linkerfehler in Bezug auf malloc und Co.

Und ja, falls es von Espriff keine angepasste Bibliothek gibt, dann wird 
das ICACHE_FLASH_ATTR Attribut wohl überall fehlen... :/

von Markus F. (mfro)


Lesenswert?

Max M. schrieb:
> deren Funktionen natürlich nicht
> das Attribute ICACHE_FLASH_ATTR aufweisen und daher in den RAM gepackt
> werden?

Kannst Du mal dein Linker-Script und das .h-File, in dem das 
ICACHE_FLASH_ATTR Macro definiert ist posten?

von Oliver S. (oliverso)


Lesenswert?

Lässt sich denn ein C++ Programm ohne Lambdas und std::funktion 
compilieren?

Eine undefined reference auf new etc. deutet ja eher auf ein 
grundsätzliches Problem hin.

Falls da die newlib verwendet wird, hilft RTFM.

Oliver

: Bearbeitet durch User
von Max M. (maxmicr)


Lesenswert?

Oliver S. schrieb:
> Lässt sich denn ein C++ Programm ohne Lambdas und std::funktion
> compilieren?

Ja, das funktioniert alles einwandfrei.

Markus F. schrieb:
> Kannst Du mal dein Linker-Script

Wie der Linker aufgerufen wird siehst du meinen Beiträgen weiter oben.

von Markus F. (mfro)


Lesenswert?

Max M. schrieb:
> Wie der Linker aufgerufen wird siehst du meinen Beiträgen weiter oben.

Ja. Und da sehe ich auch, daß ein Linker-Script (../ld/eagle.app.v6.ld) 
verwendet wird. Du weißt, was ein Linker-Script macht?

Das Script würde ich gerne sehen. Und das Macro auch.

Aber natürlich nur, falls Du (noch) Hilfe haben möchtest.

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Markus F. schrieb:
> Ja. Und da sehe ich auch, daß ein Linker-Script (../ld/eagle.app.v6.ld)
> verwendet wird.

Danke für den Hinweis. Ich hab das Dokument angehängt.

Markus F. schrieb:
> Du weißt, was ein Linker-Script macht?

Ehrlich gesagt nicht so richtig, ich würde vermuten, es bastelt aus den 
.o-Dateien eine .hex-Datei, die in den Controller geflasht wird.

Markus F. schrieb:
> Aber natürlich nur, falls Du (noch) Hilfe haben möchtest.

Unbedingt, sehr gerne. Vielen Dank!

von Lambada (Gast)


Lesenswert?

Oliver S. schrieb:
> Lässt sich denn ein C++ Programm ohne Lambdas und std::funktion
> compilieren?

Auch mit Lambda-Ausdrücken kein Problem.

Oft verwendet um z.B. Handler für HTTP-Pfade anzugeben.

z.B.
1
  //  https://github.com/esp8266/ESPWebServer/blob/master/examples/HelloServer
2
3
4
  server.on("/", handleRoot);
5
6
  server.on("/inline", [](){
7
    server.send(200, "text/plain", "this works as well");
8
  });

von tictactoe (Gast)


Lesenswert?

std::function hat seine Berechtigung. Ganz sicher aber nicht für die 
hier gestellte Aufgabe. The way to go ist, get_value_with_compare() als 
Template zu implementieren. Ich bin mir sicher, dass dann deine Probleme 
wieder auf dem Stand sind, den du mit Funktionspointern hattest (nämlich 
keine).

von Markus F. (mfro)


Lesenswert?

Das Linker-Script stopft Code aller möglichen Libraries in das 
irom0_0_seg Segment, allerdings nicht die libc.a und die libstdc++.a

Ich würde mal versuchen, diese Libraries auch dort reinzupacken, also im 
Linker-Script hinter

*libmbedtls.a:(.literal.* .text.*)

analog die libstdc++.a und libc.a aufführen.


Was versteckt sich in

"../ld/eagle.rom.addr.v6.ld"?

Das ist eine Erweiterung des Linker-Scripts, die Du noch nicht gezeigt 
hast.

: Bearbeitet durch User
von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

So, gerade wieder von der Arbeit zu Hause:

Markus F. schrieb:
> Was versteckt sich in
>
> "../ld/eagle.rom.addr.v6.ld"?

Hab ich nun auch angefügt.

Vielen Dank, dass du dir die Mühe machst, die Dateien durchzusehen!

Markus F. schrieb:
> analog die libstdc++.a und libc.a aufführen.

Also so?
1
*libstdc++.a:(.literal.* .text.*)
2
*libc.a:(.literal.* .text.*)

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Ja.

von Markus F. (mfro)


Lesenswert?

Max M. schrieb:
> Markus F. schrieb:
>> Was versteckt sich in
>>
>> "../ld/eagle.rom.addr.v6.ld"?
>
> Hab ich nun auch angefügt.

Aha. Das scheint mir der "RAM-Cache" für's ROM zu sein (viel genutzte 
Routinen im RAM gehalten). Damit wird wohl der Startup-Code rumtricksen.

Da sind auch Routinen aus der C-Library dabei. Kann sein, daß man ohne 
den Startup-Code (bzw. die libc.a) zu ändern da gar nichts tun kann.

von gdfgsdgsg (Gast)


Lesenswert?

das ist der ITCM wie bei dem größeren STM32...
instruction RAM

wenn du alles mit dem Makro markierst landet es nicht im Flash , sondern 
im ITCM  RAM
1
  iram1_0_seg :                         org = 0x40100000, len = 0x8000
2
3
  .text : ALIGN(4)
4
  {
5
    _stext = .;
6
    _text_start = ABSOLUTE(.);
7
    *(.UserEnter.text)
8
    . = ALIGN(16);
9
    *(.DebugExceptionVector.text)
10
    . = ALIGN(16);
11
    *(.NMIExceptionVector.text)
12
    . = ALIGN(16);
13
    *(.KernelExceptionVector.text)
14
    LONG(0)
15
    LONG(0)
16
    LONG(0)
17
    LONG(0)
18
    . = ALIGN(16);
19
    *(.UserExceptionVector.text)
20
    LONG(0)
21
    LONG(0)
22
    LONG(0)
23
    LONG(0)
24
    . = ALIGN(16);
25
    *(.DoubleExceptionVector.text)
26
    LONG(0)
27
    LONG(0)
28
    LONG(0)
29
    LONG(0)
30
    . = ALIGN (16);
31
    *(.entry.text)
32
    *(.init.literal)
33
    *(.init)
34
    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
35
    *(.fini.literal)
36
    *(.fini)
37
    *(.gnu.version)
38
    _text_end = ABSOLUTE(.);
39
    _etext = .;
40
  } >iram1_0_seg :iram1_0_phdr

damit liegt  laut linkerfile .text im ITCM RAM


schau das du nicht ganz so oft genutzt dinge in den  .irom0.text 
bekommst

von Markus F. (mfro)


Lesenswert?

gdfgsdgsg schrieb:
> damit liegt  laut linkerfile .text im ITCM RAM

... um das sicher sagen zu können, brauchen wir (ich zumindest) das 
Macro - aber das zeigt der TO ja nicht (trotz mehrfacher Aufforderung).

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Markus F. schrieb:
> um das sicher sagen zu können, brauchen wir (ich zumindest) das
> Macro - aber das zeigt der TO ja nicht (trotz mehrfacher Aufforderung).

Ich hab mal gesucht, ist das die Information, die du benötigst?

von Markus F. (mfro)


Lesenswert?

Max M. schrieb:
> Markus F. schrieb:
>> um das sicher sagen zu können, brauchen wir (ich zumindest) das
>> Macro - aber das zeigt der TO ja nicht (trotz mehrfacher Aufforderung).
>
> Ich hab mal gesucht, ist das die Information, die du benötigst?

Fast. Den gesamten Überblick hätten wir, wenn Du von c_types.h mal die 
Zeilen 90 - 110 oder so zeigen würdest.

P.S.: hast Du jetzt den Umbau des Linkerscripts mal ausprobiert? Laß' 
dir doch nicht immer alles einzeln aus der Nase ziehen...

: Bearbeitet durch User
von Max M. (maxmicr)


Lesenswert?

Markus F. schrieb:
> Fast. Den gesamten Überblick hätten wir, wenn Du von c_types.h mal die
> Zeilen 90 - 110 oder so zeigen würdest.
1
#define DMEM_ATTR __attribute__((section(".bss")))
2
#define SHMEM_ATTR
3
4
#ifdef ICACHE_FLASH
5
#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))
6
#define ICACHE_RODATA_ATTR __attribute__((section(".irom.text")))
7
#else
8
#define ICACHE_FLASH_ATTR
9
#define ICACHE_RODATA_ATTR
10
#endif /* ICACHE_FLASH */
11
12
#define STORE_ATTR __attribute__((aligned(4)))
13
14
#ifndef __cplusplus
15
typedef unsigned char   bool;
16
#define BOOL            bool
17
#define true            (1)
18
#define false           (0)
19
#define TRUE            true
20
#define FALSE           false

Markus F. schrieb:
> hast Du jetzt den Umbau des Linkerscripts mal ausprobiert?

Noch nicht.

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.