Forum: Compiler & IDEs Yagarto und c++


von Thorsten F. (thorstenf)


Angehängte Dateien:

Lesenswert?

Nachdem ich nun schon ein paar erste Erfolgserlebnisse mit yagarto und C 
hatte, wollte ich nun langsam auf C++ wechseln. Bevor gefragt wird, ist 
leider für die FH nötig.

Nun bin ich mir aber nicht sicher wie genau ich nun makefile und evtl 
startupcode modifizieren muss.

Derzeit verwende Ich makefile und startup code aus einem Beispielprojekt 
von Martin Thomas.

Aber alleine schon wenn ich aus dem funktionierendem C Programm, einfach 
durch ändern in cpp endungen, ein c++ Programm mache, erhalte ich einige 
Fehlermeldungen.
Hier mal der entsprechende Auszug aus dem Konsolenoutput:
1
Linking: main.elf
2
arm-elf-g++ -mthumb -mcpu=arm7tdmi-s -mthumb-interwork -I. -gdwarf-2 -DROM_RUN -DVECTORS_IN_ROM  -Os -Wall -Wcast-align -Wimplicit  -Wpointer-arith -Wswitch -ffunction-sections -fdata-sections -Wredundant-decls -Wreturn-type -Wshadow -Wunused -Wa,-adhlns=Common/src/Startup.lst  -ICommon/inc -Wcast-qual -MD -MP -MF .dep/main.elf.d Common/src/Startup.o Common/src/swi_handler.o   Common/src/timer.o Common/src/target.o Common/src/irq.o  main.o   --output main.elf -nostartfiles -Wl,-Map=main.map,--cref,--gc-sections -lc  -lm -lc  -lgcc  -lstdc++   -TCommon//LPC2378-ROM.ld
3
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-abort.o): In function `abort':
4
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\stdlib/../../../../../../../newlib-1.17.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
5
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
6
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/sbrkr.c:60: undefined reference to `_sbrk'
7
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-signalr.o): In function `_getpid_r':
8
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
9
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-signalr.o): In function `_kill_r':
10
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
11
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-writer.o): In function `_write_r':
12
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/writer.c:58: undefined reference to `_write'
13
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-closer.o): In function `_close_r':
14
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/closer.c:53: undefined reference to `_close'
15
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-fstatr.o): In function `_fstat_r':
16
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/fstatr.c:62: undefined reference to `_fstat'
17
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-isattyr.o): In function `_isatty_r':
18
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/isattyr.c:58: undefined reference to `_isatty'
19
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-lseekr.o): In function `_lseek_r':
20
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/lseekr.c:58: undefined reference to `_lseek'
21
c:/programme/yagarto/bin/../lib/gcc/arm-elf/4.4.2/../../../../arm-elf/lib/thumb/interwork\libc.a(lib_a-readr.o): In function `_read_r':
22
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\thumb\interwork\newlib\libc\reent/../../../../../../../newlib-1.17.0/newlib/libc/reent/readr.c:58: undefined reference to `_read'
23
collect2: ld returned 1 exit status
24
make: *** [main.elf] Error 1

Sollten diese Referencen nicht durch die "Masse" an libraries 
(libc,libm,libgcc und libstdc++) erschlagen sein?
Irgendwo hatte mir google auch schon geraten ich solle noch syscalls.o 
mitlinken. Diese Datei habe ich jedoch nicht. Ich weiss nichtmal wie der 
linker auf die idee kommt in C:\msys\... zu suchen, da ich überhaupt 
kein msys habe!

Bin für jeden Tipp dankbar.

von Karl H. (kbuchegg)


Lesenswert?

Das sind alles 'undefined references' auf Funktionen die in einer 
Standard-Runtime Library enthalten sein sollten.

Entweder fehlt dir noch irgendeine Standard-Library, die dazugelinkt 
werden muss, oder die Reihenfolge des Libraries ist falsch.

Sorge mal dafür, dass die C-Runtime Libarary als letztes dazugelinkt 
wird.

von (prx) A. K. (prx)


Lesenswert?

Diese Funktionen müssen vom Anwender zur Verfügung gestellt werden, 
damit die darauf aufsetzende Newlib funktionieren kann. Ebendiese 
syscalls, zu dem man sicher im Netz was finden (als Quellcode 
natürlich). Teilweise sind das einfach Dummies. Die Newlib kann nicht 
wissen, worauf stdout irgendwas ausgeben soll. Ebenso fehlt der Newlib 
die Erkenntnis von der Speicheraufteilung und stützt sich folglich suf 
die Pseudo-Systemfunktion _sbrk.

Alternativ kann man versuchen, herauszufinden was genau die Newlib 
reinzieht - möglicherweise die Speicherallokation von C++, oder das 
Exception Handling - und diesen Teil deaktivieren/rauswerfen/ersetzen um 
die Newlib zu vermeiden.

von Thorsten F. (thorstenf)


Lesenswert?

Ok dann such ich mal weiter. Wenn ich diese Funktionen selbst 
implementieren möchte, wo find ich denn die Information welche dieser 
Funktionen was tun soll?
Und müsste ich bei der implementierung etwas gesondert beachten? 
Beispielsweise hab ich mal z.b. mal void _sbrk(){} in den Hauptquelltext 
eingefügt, der entsprechende Fehler verschwindet dadurch jedoch nicht.

von Sepp (Gast)


Lesenswert?

http://neptune.billgatliff.com/newlib.html

Auf der Yagarto Homepage gabs auch mal ein Beispiel zur syscalls.c.

von 900ss (900ss)


Lesenswert?

Bei Martin Thomas gibt es ein Beispielprojekt für C++. In dem ZIP-File 
ist auch die syscalls.c enthalten. Die fehlt dir hier. Die Seite ist 
auch sonst eine sehr gute "Fundgrube" für Beispiele, die einem weiter 
helfen (mir zumindest :-)). Danke nochmal an Thomas.

http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html#at91_cpp

Gruß Joachim

von Thorsten F. (thorstenf)


Lesenswert?

Ich glaube alleine schon aus Platzgründen dürfte es wohl das beste sein 
wenn ich versuche nur das "nötigste" einzubinden.

Mein bisheriger Stand ist, dass ich ohne einbinden jeglicher 
Bibliotheken ein einfaches C++ Projekt erstellen/kompilieren kann, und 
in diesem auch erfolgreich eine Klasse instanziere. Sobald ich jedoch 
den new bzw den delete operator brauche, funktioniert das ganze 
(logischerweise) erstmal wieder nicht. In dem Fall erhalte ich folgenden 
Konsolenoutput:
1
main.o: In function `main':
2
D:\workspace\merses\c++ nolibs yagarto/main.cpp:17: undefined reference to `_Unwind_SjLj_Register'
3
D:\workspace\merses\c++ nolibs yagarto/main.cpp:28: undefined reference to `operator new(unsigned long)'
4
D:\workspace\merses\c++ nolibs yagarto/main.cpp:28: undefined reference to `operator delete(void*)'
5
D:\workspace\merses\c++ nolibs yagarto/main.cpp:28: undefined reference to `_Unwind_SjLj_Resume'
6
D:\workspace\merses\c++ nolibs yagarto/main.cpp:29: undefined reference to `operator delete(void*)'
7
D:\workspace\merses\c++ nolibs yagarto/main.cpp:29: undefined reference to `_Unwind_SjLj_Unregister'
8
D:\workspace\merses\c++ nolibs yagarto/main.cpp:40: undefined reference to `__gxx_personality_sj0'
9
collect2: ld returned 1 exit status
10
make: *** [main.elf] Error 1

Binde ich alle Bibliotheken ein, sowie die modifizierte syscalls.c ist 
es mir auch möglich den Code erfolgreich zu kompilieren, jedoch wächst 
er von ~1600bytes auf ~63kbytes und der Debugger "springt nicht mehr an" 
(hängt bei 27%)

Hat hier noch jemand nen tipp evtl?

von mthomas (Gast)


Lesenswert?

Wenn richtig erinnert, ziehen die Standardfunktionen für new und delete 
die stdio-Funktionen inkl. floating-point mit in das Binary. 
Wahrscheinlich für eine Fehlerausgabe über iostreams und mgwl. auch 
exception-handling wg. "unwind". Habe den Quellcode der newlib grade 
nicht zur Hand um nachzusehen um nachzusehen aber der heftigt Anstieg 
der Binarygröße deutet darauf hin.

Dies kann man verhindern, in dem man new und delete mit simplen eigenen 
Funktion "überschreibt", die nur malloc und free enthalten. Etwas mehr 
dazu findet man in Dokumenten der Fa. Quantum Leaps.

Ansonsten mag eines meiner Beispiele hilfreich sein:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#cm3_cpp1
Das Beispiel ist noch recht neu und für Cortex-M3/STM32 aber in Bezug 
auf C++ nicht abhängig vom Controller-Kern. Von Interesse düfte die 
Datei mini_cpp.cpp sein.


In Bezug auf "Debugger springt nicht an" kann ich ohne ein paar mehr 
Informationen nichts schreiben aber vielleicht fällt jemand anderem 
etwas dazu ein.

von Thorsten F. (thorstenf)


Angehängte Dateien:

Lesenswert?

Hmm nachdem sich weder in der von Yagarto mitgelieferten, noch in der 
durch cygwin bereitgestellten stdlib.h die Prototypen von malloc() und 
free() finden lassen, fühle ich mich versucht doch erstmal wieder mit 
dem Einsatz aller Bibliotheken ein Ergebnis zu erzielen.

Damit wäre ich wieder bei dem "der debugger springt nicht an" Problem. 
Da ich selbst recht ratlos bin, weiss ich leider nicht genau welche 
Informationen notwendig sind. Deshalb hänge ich erstmal mein Projekt in 
gepackter Form an.

An Software verwende ich (unter win xp sp3):

Eclipse + gnuarm plugin + zylin cdt
cygwin (make etc)
Yagarto
openOCD 0.2.0 SR 1 (von Freddie Chopin)

openOCD wird als externes Tool mit folgenden Argumenten aufgerufen:
1
-f C:\Programme\OpenOCD\0.2.0\interface\olimex-arm-usb-ocd.cfg
2
-f C:\Programme\OpenOCD\0.2.0\target\lpc2378.cfg

Danach starte ich den Debugvorgang als "zylin embedded Debug" mit den 
Argumenten:
1
target remote localhost:3333
2
monitor sleep 500
3
monitor poll
4
monitor flash probe 0
5
monitor flash erase_sector 0 0 0
6
monitor flash write_image main.bin 0x0
7
monitor reset run
8
monitor sleep 500
9
monitor soft_reset_halt
10
symbol-file main.elf
11
thbreak main
12
continue

Normalerweise (zumindest derzeit für mich ;) )muss ich diesen 
Debugprozess einmal neustarten, damit der Code wirklich auf dem Board 
ist, und ich diesen auch debuggen kann (beim ersten Versuch hängt es 
auch einfach bei 27%)
Hier allerdings hat das noch nicht geholfen :/

von (prx) A. K. (prx)


Lesenswert?

Thorsten F. schrieb:

> D:\workspace\merses\c++ nolibs yagarto/main.cpp:17: undefined reference
> to `_Unwind_SjLj_Register'

Wenn man auf Exception-Handling und RTTI verzichten kann und dies dem 
Compiler mitteilt, dann wird man manche solchen Dinger automatisch los.

von Thorsten F. (thorstenf)


Lesenswert?

Vielen Dank, das hat die Anzahl meiner Fehler beim Versuch ohne 
Bibliotheken schonmal verringert. Derzeit beschwert er sich nur noch 
darüber dass er keine Prototypen für malloc und free findet.

Sieht wohl leider so aus als würd ich zumindest um einige libs nicht 
herumkommen :/

von (prx) A. K. (prx)


Lesenswert?

malloc/free entweder nicht verwenden oder selbst implementieren. Im 
einfachsten Fall alloziert malloc stetig aufsteigend ab dem Ende des 
statisch allozierten RAMs, mit sanity check gegen den absteigenden Wert 
vom Stackpointer oder gegen das Speicherende, je nach 
Speicheraufteilung, und free ist leer.

Möglicherweise kann man dafür als Basis auch eine fertige Lib bzw. den 
Teil der Newlib verwenden, nur sollte man das ggf. so modifizieren, dass 
ein dort drin identifizierter Fehlerfall oder irgendwelches Tracing 
nicht über printf() die halbe Newlib hinter sich herzieht.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Thorsten F. schrieb:
> Hmm nachdem sich weder in der von Yagarto mitgelieferten, noch in der
> durch cygwin bereitgestellten stdlib.h die Prototypen von malloc() und
> free() finden lassen, fühle ich mich versucht doch erstmal wieder mit
> dem Einsatz aller Bibliotheken ein Ergebnis zu erzielen.

malloc und free sind zumindest bei Codesourcery G++ lite (basiert wie 
Yagartos toolchain auf den GNU Quellen) schon in stdlib.h. Die 
Prototypen sehen aber bei der newlib in Macros verpackt, also nicht nach 
malloc( suchen sonder nur nach malloc. cygwin Header-Files haben mit dem 
Cross-Compiler nichts zu tun, dort sucht man an der falschen Stelle.

Eine kleine C++ Demo-Anwendung ohne stdio-Funktion, excpetions und RTTI 
für STM32 (ähnlich die aus dem Link oben) benötigt hier inkl. aller 
Initialisierungen für STM32 ca. 13kBytes Flash-Speicher aber wenn 
mini_cpp.cpp nicht angelinkt wird ca. 40 kBytes. Es lohnt sich also 
schon, da etwas dranzubleiben und nicht auf "Einsatz aller Bibl." zu 
setzen. Die mini_cpp.cpp Datei von QL aus dem o.g. Link einfach 
mitcompilieren/linken sollte reichen. Damit wird new und delete durch 
simple Funktionen mit malloc und free ersetzt.

> Damit wäre ich wieder bei dem "der debugger springt nicht an" Problem.
> Da ich selbst recht ratlos bin, weiss ich leider nicht genau welche
> Informationen notwendig sind. Deshalb hänge ich erstmal mein Projekt in
> gepackter Form an.
>
> An Software verwende ich (unter win xp sp3):
>
> Eclipse + gnuarm plugin + zylin cdt
> cygwin (make etc)
> Yagarto
> openOCD 0.2.0 SR 1 (von Freddie Chopin)
>
> openOCD wird als externes Tool mit folgenden Argumenten aufgerufen:
>
>
1
> -f C:\Programme\OpenOCD\0.2.0\interface\olimex-arm-usb-ocd.cfg
2
> -f C:\Programme\OpenOCD\0.2.0\target\lpc2378.cfg
3
>

init?

> Danach starte ich den Debugvorgang als "zylin embedded Debug" mit den
> Argumenten:
>
>
1
> target remote localhost:3333
2
> monitor sleep 500
3
> monitor poll
4
> monitor flash probe 0
5
> monitor flash erase_sector 0 0 0
6
> monitor flash write_image main.bin 0x0
7
> monitor reset run
8
> monitor sleep 500
9
> monitor soft_reset_halt
10
> symbol-file main.elf
11
> thbreak main
12
> continue
13
>

Ich würde zumindest noch ein halt einfügen (bei LPC mglw. 
soft_reset_halt) vor poll und probe. erase_sector Paraemterbeschreibung 
nachgelesen? Sicher, dass genug Flash-Sektoren gelöscht werden? Man kann 
bei neueren OpenOCD direkt mit den Daten aus dem elf-file flashen und 
benötigte die benötigten Sektoren automatisch vorher löschen lassen: 
flash write_image erase main.elf und spart sich das extra erase_sector. 
Extra Angabe für symbol-file bisher selbst nie gebraucht. Wenn man im 
CDT hardware-debugging plugin das elf-File angibt, braucht man das 
nicht, k.A. ob beim Zylin-plugin auch so. Testweise also:

In der Debug-Config. bei Main/C/C++ Appl. die elf-Datei auswählen.

Dann bei Startup Init:
[code]
monitor soft_reset_halt
set mem inaccessible-by-default off
load
compare-sections
[code]

compare-sections vergleicht Inhalt der relevaten sectios aus der 
elf-Datei mit dem Inhalt des Flash-Speichers. Damit kann man erstmal 
prüfen, ob der flash-Vorgang erfolgreich war.

Bei Runtime-Options:
[x] Set BP at main
[x] Resume

Angaben beziehen sich auf CDT Hardware-Debugging Plugin. Das ist der 
quasi "offizielle" Ersatz der Elcipse CDT-Macher für des Zylin Plugin. 
Der Entwickler des CDT plugins hat sich auch stark am Zylin-Plugin 
orientiert - Optionen sind also hoffentlich ähnlich (Zylin nie selbst 
genutzt).

> Normalerweise (zumindest derzeit für mich ;) )muss ich diesen
> Debugprozess einmal neustarten, damit der Code wirklich auf dem Board
> ist, und ich diesen auch debuggen kann (beim ersten Versuch hängt es
> auch einfach bei 27%)
> Hier allerdings hat das noch nicht geholfen :/

Mglw. wird der Controller beim ersten Mal nicht richtig angehalten. Wie 
sieht es ohne Eclipse/Plugins etc aus? Kann man über OpenOCD 
telnet-Schnittstelle problemlos flashen? Damit kann man zumindest 
testen, ob die config-Datei aus der OpenOCD target-library das macht, 
was man erwartet und das Programm auf dem Controller auch anläuft.

Nutze selbst einen anderen Satz Tools (kein gnuarm plugin - nur 
makefile, kein cygwin/mingw/msys etc - nur noch cs-make und cs-rm aus 
den Codesourcery-Paket als shell-tools und die Win32 shell (cmd.exe) 
statt cygwin od. msys bash, CS G++ lite arm-eabi statt Yagarto, 
selbstkompiliertes OpenOCD für Treiber direkt von FTDI statt dem Paket 
von F.C. für libusb, Amontec JTAGkey(2) statt Olimex-Adapter) und habe 
mit LPC23xx schon eine Weile nichts mehr gemacht - mglw. sind meine 
Hinweise also nicht unmittelbar übertragbar.

von Thorsten F. (thorstenf)


Angehängte Dateien:

Lesenswert?

Vielen Dank, ihr habt mir bereits sehr geholfen. Dank der mini_cpp.cpp 
habe ich nun zum ersten Mal erfolgreich dynamisch ein Objekt angelegt 
bei nur 6kb codegröße :)

Es scheint allerdings tatsächlich ein Problem mit dem Flashen zu geben. 
Wobei ich jetzt keinen Unterschied zwischen der Ausführung in Eclipse 
bzw über die commandline feststellen konnte.

Im Anhang ist ein Bild wie die Ausgabe über die commandline aussieht.
Hier der Konsolenoutput von eclipse:
1
target remote localhost:3333
2
0x7fffe152 in ?? ()
3
monitor soft_reset_halt
4
requesting target halt and executing a soft reset
5
target state: halted
6
target halted in ARM state due to debug-request, current mode: Supervisor
7
cpsr: 0xa00000d3 pc: 0x00000000
8
set mem inaccessible-by-default off
9
load
10
Loading section .text, size 0x11b8 lma 0x0
11
Loading section .data, size 0x838 lma 0x11b8
12
Start address 0x0, load size 6640
13
Transfer rate: 3 KB/sec, 3320 bytes/write.
14
compare-sections
15
Section .text, range 0x00000000 -- 0x000011b8: MIS-MATCHED!
16
Section .data, range 0x000011b8 -- 0x000019f0: matched.
17
warning: One or more sections of the remote executable does not match
18
the loaded file
19
20
monitor sleep 500
21
monitor poll
22
background polling: on
23
TAP: lpc2378.cpu (enabled)
24
target state: halted
25
target halted in ARM state due to breakpoint, current mode: Supervisor
26
cpsr: 0xa00000d3 pc: 0x00000000
27
monitor soft_reset_halt
28
requesting target halt and executing a soft reset
29
target state: halted
30
target halted in ARM state due to breakpoint, current mode: Supervisor
31
cpsr: 0xa00000d3 pc: 0x00000000
32
monitor flash probe 0
33
flash 'lpc2000' found at 0x00000000
34
monitor flash write_image erase main.elf
35
auto erase enabled
36
Padding image section 0 with 0 bytes
37
Verification will fail since checksum in image(0xe1a00000) written to flash was different from calculated vector checksum(0xb8a06f58).
38
To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.
39
wrote 6640 byte from file main.elf in 1.796875s (3.608696 kb/s)
40
compare-sections
41
Section .text, range 0x00000000 -- 0x000011b8: MIS-MATCHED!
42
Section .data, range 0x000011b8 -- 0x000019f0: matched.
43
warning: One or more sections of the remote executable does not match
44
the loaded file
45
46
monitor reset run
47
JTAG tap: lpc2378.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
48
JTAG Tap/device matched
49
monitor sleep 500
50
monitor soft_reset_halt
51
requesting target halt and executing a soft reset
52
target state: halted
53
target halted in ARM state due to debug-request, current mode: Supervisor
54
cpsr: 0xa00000d3 pc: 0x00000000
55
symbol-file main.elf
56
thbreak main
57
Hardware assisted breakpoint 1 at 0x21e: file main.cpp, line 17.
58
Current language:  auto; currently asm
59
continue
60
main () at main.cpp:17
61
17      PINSEL10 = 0;                         /* Disable ETM interface, enable LEDs */
62
Current language:  auto; currently c++

Es gibt also doch eindeutig Probleme wie
"Section .text, range 0x00000000 -- 0x000011b8: MIS-MATCHED!"
unmissverständlich mitteilt. Dennoch läuft das Programm auf dem Board 
und ich kann auch mit new und delete arbeiten.

Was genau ist denn der Unterschied zwischen load und flash write_image?

von Thorsten F. (thorstenf)


Lesenswert?

Seltsam, ich kann meinen eigenen Beitrag nicht bearbeiten -.-
Mittlerweile hatte ich tatsächlich auch mal Probleme den Flash zu 
löschen:
1
monitor flash write_image erase main.elf
2
auto erase enabled
3
Padding image section 0 with 0 bytes
4
memory write caused data abort (address: 0x40000008, size: 0x4, count: 0x6)
5
lpc2000 prepare sectors returned 11689384
6
failed erasing sectors 0 to 1 (-902)

Dies passiert aber nicht grundsätzlich. Seltsamerweise funktioniert es 
wohl meistens.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Erstmal dieser Sache nachgehen:
1
Verification will fail since checksum in image(0xe1a00000) written to flash was different from calculated vector checksum(0xb8a06f58).
2
To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.

Das Programm läuft nicht an, wenn die Prüfsumme nicht stimmt. Mit 
neueren Versionen von OpenOCD hatte ich auch etwas damit zu kämpfen, gab 
wohl Änderungen in OpenOCD. Aber selbst wenn OpenOCD eine aus den 
übrigen Werten korrekt berechnete Prüfsumme automatisch einsetzt, 
bekommt gdb davon nichts mit und meckert eine Abweichung an.

Dem Ganzen kann man aus dem Weg gehen, in dem man die korrekte Prüfsumme 
per .word im Quellcode angibt (das ist wohl mit "inject correct 
checksum" gemeint). Quellcode für ARM7 exceptions vector sollte in 
einer/der einzigen Assemblerdatei zu finden sein. Für .text sollte dann 
auch "matched." erscheinen, sonst sind alle folgende Experimete nur 
Blindflug. Zum Debuggen kann man auch OpenOCDs verify_image nutzen, dies 
gibt die Speicherstelle der ersten Abweichung aus.

von Thorsten F. (thorstenf)


Lesenswert?

Soweit ich das verstanden habe muss die Prüfsumme hier:
1
Reset_Addr:      .word     Reset_Handler
2
Undef_Addr:      .word     Undef_Handler
3
SWI_Addr:        .word     SWI_Handler
4
PAbt_Addr:       .word     PAbt_Handler
5
DAbt_Addr:       .word     DAbt_Handler
6
                 .word     0xb8a06f58  @Prüfsumme
7
IRQ_Addr:        .word     IRQ_Handler
8
FIQ_Addr:        .word     FIQ_Handler
angegeben werden.

Die Anpassung dieser Zeile hat jedoch keinerlei Effekt auf diese 
Warnung. Hatte auch schon gelesen man könne diese Warnung ignorieren, 
und da ich teilweise trotz dieser Warnung damit arbeiten konnte bin ich 
davon ausgegangen dass es bei meiner Version keinerlei Unterschied 
macht.

Edit: Auch wenn es einen Effekt hätte, würde es mich doch ein wenig 
ärgern nach jeder Codeänderung manuell die Prüfsumme anpassen zu müssen. 
Besteht die Möglichkeit das zu automatisieren bzw diese Überprüfung zu 
deaktivieren?

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Thorsten F. schrieb:
> Soweit ich das verstanden habe muss die Prüfsumme hier:
>
>
1
> Reset_Addr:      .word     Reset_Handler
2
> Undef_Addr:      .word     Undef_Handler
3
> SWI_Addr:        .word     SWI_Handler
4
> PAbt_Addr:       .word     PAbt_Handler
5
> DAbt_Addr:       .word     DAbt_Handler
6
>                  .word     0xb8a06f58  @Prüfsumme
7
> IRQ_Addr:        .word     IRQ_Handler
8
> FIQ_Addr:        .word     FIQ_Handler
9
>
> angegeben werden.

Hmm, zu wenig Context für mich. Aber die Prüfsumme kommt nicht in die 
Adressenliste sondern ins sechte Element des Exceptions-Vectors 
(beginnend bei 0x14).

> Die Anpassung dieser Zeile hat jedoch keinerlei Effekt auf diese
> Warnung. Hatte auch schon gelesen man könne diese Warnung ignorieren,
> und da ich teilweise trotz dieser Warnung damit arbeiten konnte bin ich
> davon ausgegangen dass es bei meiner Version keinerlei Unterschied
> macht.

Es geht weniger um die Warnung, sondern darum, per OpenOCD verify_image 
oder gdb compare-sections sicherzustellen, dass der Maschinencode 
korrekt übertragen wurde. Wenn verify_image "verified in xx sec" bzw. 
compare-section "matched" ausgibt, braucht man sich darüber zuminderst 
erstmal keine Gedanken mehr zu machen.

> Edit: Auch wenn es einen Effekt hätte, würde es mich doch ein wenig
> ärgern nach jeder Codeänderung manuell die Prüfsumme anpassen zu müssen.
> Besteht die Möglichkeit das zu automatisieren bzw diese Überprüfung zu
> deaktivieren?

OpenOCD hat die Funktion, die Prüfsumme zu berechnen und einzusetzen. 
Der Vergleich ist optional, gdb compare-sections der OpenOCD 
verify_image sind nur Kür aus o.g. Grund - also "deaktivieren" durch 
nicht-aufrufen.

gdb compare-sections und OpenOCD verfiy_image berücksichtigen die 
"untergeschobene" Änderung nicht und melden Abweichungen. Meine Tests 
sind aber schon eine Weile her, kann inzwischen mglw. anders sein und 
man hat eine Sonderbehandlung für LPC2k in OpenOCD eingebaut. Im Zweifel 
per OpenOCD developer-mailingliste nachfragen und evtl. die 
Funktionalität wünschen.

Man kann Code so schreiben, dass die in der Prüfsumme berücksichtigen 
Speicheradressen und damit auch die Prüfsumme selbst immer gleich sind.

von Thorsten F. (thorstenf)


Lesenswert?

Vielen Dank, ich konnte die entsprechende Warnung nun loswerden. Die 
Checksumme steht nun im Exceptionvektor:
1
Vectors:        LDR     PC, Reset_Addr         
2
                LDR     PC, Undef_Addr
3
                LDR     PC, SWI_Addr
4
                LDR     PC, PAbt_Addr
5
                LDR     PC, DAbt_Addr
6
                .word  0xb8a06f58      @ Reserved Vector for checksum
7
                LDR     PC, IRQ_Addr
8
@@                LDR     PC, [PC, #-0x0120]     @ Vector from VicVectAddr
9
                LDR     PC, FIQ_Addr

Mein Programm scheint nach wie vor auch zu funktionieren, den mismatch 
der .text section bin ich jedoch leider dadurch nicht losgeworden :/
1
target remote localhost:3333
2
0x7fffe152 in ?? ()
3
set mem inaccessible-by-default off
4
monitor sleep 500
5
monitor poll
6
background polling: on
7
TAP: lpc2378.cpu (enabled)
8
target state: halted
9
target halted in Thumb state due to debug-request, current mode: Supervisor
10
cpsr: 0xa00000f3 pc: 0x7fffe152
11
monitor flash probe 0
12
flash 'lpc2000' found at 0x00000000
13
monitor flash write_image erase main.elf 0x0
14
auto erase enabled
15
Padding image section 0 with 0 bytes
16
wrote 7616 byte from file main.elf in 2.015625s (3.689922 kb/s)
17
compare-sections
18
Section .text, range 0x00000000 -- 0x00001588: MIS-MATCHED!
19
Section .data, range 0x00001588 -- 0x00001dc0: matched.
20
warning: One or more sections of the remote executable does not match
21
the loaded file
22
23
monitor verify_image main.elf
24
checksum mismatch - attempting binary compare
25
Verify operation failed address 0x00000001. Was 0x40 instead of 0xf0
26
27
Runtime error, file "command.c", line 469:
28
    
29
monitor reset run
30
JTAG tap: lpc2378.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
31
JTAG Tap/device matched
32
monitor sleep 500
33
monitor soft_reset_halt
34
requesting target halt and executing a soft reset
35
target state: halted
36
target halted in ARM state due to debug-request, current mode: Supervisor
37
cpsr: 0xa00000d3 pc: 0x00000000
38
symbol-file main.elf
39
thbreak main
40
Hardware assisted breakpoint 1 at 0x33e: file main.cpp, line 23.
41
continue
42
main () at main.cpp:23
43
23      lcd_init();

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.