Ich bin mir jetzt nicht sicher wo das problem ist. Funktioniert mein
Debugger nicht richtig oder ist das erstellte binary fehlerhaft?
Eigentlich habe ich nur eine while(1); in der main. Klar kann es an den
eclipse build options liegen oder am verwendeten linker file (Anhang).
Vielmehr habe ich aber meine Toolchain "arm-none-eabi-" version 5.3.0 im
Verdacht. (Arch Linux)
Hat jemand eine Idee?
Gruss,
Pascal
K.A. was es da hat, sieht nach debugger aus. Was hängt da dran?
Eventuell Adapter-Speed reduzieren?
Binary liesse sich durch einen Blick ins Disassembly überprüfen.
ich bin kein OOCD Experte, habe das mit einer anderen config gerade zum
Laufen bekommen. Dein Problem mit 'JTAG-DP OVERRUN' liefert aber massig
Treffer bei Tante Google.
Hey vielen Dank für die Rückmeldungen.
Ja ich weis dass google viele Treffer liefert aber die haben mir nicht
weitergeholfen :(
Ich habe einen BusBlaster v4 (leider) als Debugger. Da ich eigentlich
SWD brauche habe ich mir eine KT-Link Buffer Logic auf den Debugger
geflasht, da die originale JTAGKey kein SWD unterstützt. Leider finde
ich jetzt nirgendwo im Netz die alte JTAGKey Buffer Logic für den BBv4
um das rückgängig zu machen. Das BusBlaster Projekt von
DangerousPrototypes schein schon seit mehreren Jahren tot zu sein :(
Daher bin ich jetzt relativ unsicher ob das binary der Fehler ist oder
mein Debugger. Ein laufendes Programm anhalten und wieder starten
funktioniert ja, das flashen scheinbar auch.
Da jetzt noch ein Toolchain update dazukam weis ich gar nicht mehr wo
ich anfangen soll.
Wie kann ich das binary via Disassable prüfen?
Ich werde mal mit Keil unter windows ein lauffähiges binary erzeugen und
dieses dann unter linux mit openocd flashen.
ein lauffähiges Programm für das Board findest du hier:
Beitrag "FFT mit Wasserfall auf dem LPC1768"
Ich habe noch einen abgesägten LPCLink von einem LPCXpresso über, denn
kannst du haben wenn es dir hilft. Ansonsten würde ich einen LPCLink V2
nehmen, der kann CMSIS-DAP und kostet knappe 20€ bei Watterott. Dann
hast du wenigstens ein Stück funktionierende Hardware, die vielen
offenen Baustellen machen das nicht einfach.
Ich habe einen Ulink 2 aus china, mit dem hat Debuggen mit Keil unter
Windows wunderbar funktioniert. Auch SWD ist damit problemlos möglich.
Nur wollte ich eben das ganze mit Linux und OpenOCD realisieren.
Ich melde mich wenn es was zu erzählen gibt ;)
arm-none-eabi-objdump -S path-to-image.elf, und schaun ob da was
vernünftiges daherkommt ;-)
Pascal H. schrieb:> Da ich eigentlich> SWD brauche habe ich mir eine KT-Link Buffer Logic auf den Debugger> geflasht, da die originale JTAGKey kein SWD unterstützt.
Ich hab keine Ahnung vom BusBlaster, aber es sieht so aus als würde JTAG
verwendet? Warum nicht gleich SWD verwenden wenn die SWD-Firmware auf
dem Busblaster ist?
Zur Not funktioniert auch ein st-link von einem nucleo mit dem lpc in
Verbindung mit openocd. Besser ists aber sicher da einen gscheiten
Debugger zu verwenden, und da eine Unsicherheit wenn was spinnt halbwegs
sicher ausgeräumt zu haben.
Pascal H. schrieb:> Wie kann ich das binary via Disassable prüfen?
arm-none-eabi-gdb kennt "disassemble". Außerdem gibts noch -objdump.
Pascal H. schrieb:> Da ich eigentlich> SWD brauche habe ich mir eine KT-Link Buffer Logic auf den Debugger> geflasht, da die originale JTAGKey kein SWD unterstützt.
Das ist veraltet. Alle FTDI-basierten Adapter unterstützen neuerdings
SWD,
als Buffer nimmt man einen 74HC126 oder einfach einen 400Ohm - 1k
Widerstand. Anleitung müsste bei neuerem OpenOCD dabei sein. Habe ich
selber mit meinem JTAGKey2 gemacht, funktioniert.
LPC17xx hat gerne mal DP-Overruns bei Änderungen des Takts (PLL
einschalten), was auch der ROM-Bootloader macht.
Ein direkt mit "flash write" geflashtes Binary hat i.d.R. eine defekte
Vektor Checksumme (siehe UM10360.pdf) und läuft daher nicht an, es
läuft dann der Bootloader. Lädt man via gdb (wie oben erwähnt) wird die
Checksumme automagisch repariert. Allerdings kann dann ein Verify an der
Stelle fehlschlagen.
Hey, ich habe ordentliche Fortschritte gemacht :)
Nachdem ich in Windows mit Keil ein kleines LED Blink example erstellt
hatte und dies auch wunderbar lief, habe ich das erstellte binary
versucht mit openocd und meinem Busblaster zu flashen.
Mit dieser openocd config laeuft der Busblaster ohne irgendwelche JTAG
Fehler:
Soweit sogut.
Danach habe ich das kleine Beispielprogramm in eclipse mit der
arm-none-abi- 5.3.0 gebaut und geflasht. Leider ohne Erfolg. Eine LED
leuchtet. (Gleiches Bild wie beim GDB Flash des Keil Binaries). Ja ich
habe mit telnet und gdb versucht zu flashen.
Naja werde morgen weiter testen. Hab so das Gefuehl das koennte klappen
:)
Gruss
Pascal H. schrieb:> Reading symbols from lpc_test2.axf...> warning: Loadable section "RW_IRAM1" outside of ELF segments> done.
Das ELF(?) Binary will in den RAM und nicht in den Flash schreiben. Das
geht so nicht. Vermutlich eine Inkompatibilität der Tools, dann hilft
oft ein Export nach ihex oder binary (raw ohne ELF Header).
Ja die Warning habe ich auch gesehen. Aber warum funktioniert dann das
flashen über telnet?
Leider weis ich nicht genau was es mit dem ELF Header auf sich hat. Dazu
muss ich mir erst ein wenig Literatur anschauen.
Das lpc_test2.axf wurde mit der Keil ARM C/C++ Compiler Toolchain
erstellt.
Ein objdump -S zeigt ELF32.
Die Positionierung im binary wird doch über das lpc17xx.ld also das
Linker Script gesteuert oder? Ggf. ist dort irgendwas falsch.
Jim M. schrieb:> Ein direkt mit "flash write" geflashtes Binary hat i.d.R. eine defekte> Vektor Checksumme (siehe UM10360.pdf) und läuft daher nicht an, es> läuft dann der Bootloader. Lädt man via gdb (wie oben erwähnt) wird die> Checksumme automagisch repariert. Allerdings kann dann ein Verify an der> Stelle fehlschlagen.
Die OpenOCD korregiert die Checksumme schon seit einiger Zeit, wenn man
via "program" das ELF-file direkt flasht. Verify schlägt aber immer noch
fehl.
Das hat mich letzte Woche so genervt, das ich mich mal hingesetzt habe
und ein kleines tool geschrieben habe, welches die Checksumme gleich im
ELF fixed.
http://hilbert-space.de/?p=178
Läuft unter Cygwin und Linux.
Vielleicht findet es ja der eine oder andere hilfreich. Ich zumindest
will den Verify step nach dem Flashen nicht mehr missen. Das hat mir bis
jetzt schon vor so mancher unnötiger Debug-Session bewahrt.
Pascal H. schrieb:> Mit dem gdb laesst sich zwar das binary flashen aber es laeuft nicht :(> eine led brennt, es sollten aber beide im wechsel leuchten...
Hi Pascal,
wenn Du mir sagst, an welchen Pins deine LEDs hängen und wie schnell
dein Quarz ist, dann kann ich dir schnell ein kleinen Blinker schreiben
und dir ein getestetes binary senden. Das schließt zumindest schon mal
eine Fehlerquelle aus.
Gruß,
Nils
Hey Nils,
die LED's hängen an 3,25 und 3,26
Der Quarz hat 12M
Baust du das binary mit dem arm-none-eabi- v5.3.0 ?
Weil das Keil Binary von Windows läuft ja.
Schonmal vielen Dank :)
So, HelloWorld ist anbei. Bei mir blinkt das auch mit 150ms
Periodendauer.
die GCC Version, die ich benutzte ist etwas älter, da ich ein paar alte
Libs benutze die auch mit dem gebaut wurden.
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529
(release) [ARM/embedded-4_9-branch revision 227977]
Gruß,
Nils
Ok vielen Dank, ich werde das binary heute abend mal flashen.
Wenn das problemlos läuft kann es an meiner toolchain, an den eclipse
build options die ich eingestellt habe oder was ich am meisten vermute
an meinem linker script liegen.
Nils kannst du mir deins mal anhängen?
Werde jetzt mal mit deinem linker script experimentieren, aber ich
glaube ich brauche noch das startup Assembler/C++ File weil mir fehlen
so einige references
Leider kann ich meinen vorherigen Beitrag nicht mehr bearbeiten.
Ich habe mir mittlerweile das mbed src repo besorgt
(https://developer.mbed.org/users/mbed_official/code/mbed-src/) und alle
notwendigen cmsis / linker files in einem testprojekt erstellt. (Anhang)
Das flashen funktioniert ohne Fehlermeldung. Nach einem run wird aber
nur die erste GPIO conf gesetzt, danach steht das Program.
Ich musste an den compiler settings "--specs=nosys.specs" hinzufuegen,
sonst sucht er nach "reference _exit".
##########################
Auweia ... ich glaub es liegt daran weil der Systick Handler nicht
kommt.
Muss ich den mit NVIC freischalten ?!? ... muss ich morgen mal schauen.
##########################
Pascal H. schrieb:> ich glaub es liegt daran weil der Systick Handler nicht> kommt.> Muss ich den mit NVIC freischalten ?!?
Nein. Systick ist kein Interrupt vom NVIC und deshalb dort auch nicht
freischaltbar. Man kann ihm allerdings via NVIC_SetPriority() eine
Priorität zuweisen.
Hallo Nils,
hier das binary. Wenn ich mir das mit objdump anschaue sieht es sehr
sehr viel anders aus als dein HelloWorld.elf
In deinem ist nur eine grosse .text section
In meinem sind die einzelnen Funktionen zu sehen
Was mir auch aufgefallen ist, in meinem sind die ganzen System
spezifischen Funktionen wie
_sbrk
_sbrk_r
memcpy
_malloc_r
...
implementiert ... ist das falsch?
Habe ich meine compiler options nicht richtig eingestellt ..
Hmm
irgendwie machst du es dir aber auch schwer. Lade doch mal dieses Paket:
https://github.com/adamgreen/gcc4mbed
Das ist, wie der Name schon sagt, die mbed lib für gcc. Die gcc
toolchain wird beim Start des OS-install scripts heruntergeladen. Dann
wird ein BuildShell.cmd erzeugt das man startet und darin kann man das
make ausführen. Es sind verschiedene Beispiele drin, das Blink ist ganz
rudimentär ohne c++ Funktionen. Als zweites vielleicht den Ticker
ansehen, ist eine sehr schöne Timer Implementierung.
Eine Quickstart Beschreibung ist hier:
https://developer.mbed.org/users/AdamGreen/notebook/gcc4mbed/
einen habe ich noch:
dein Systick_Handler wird nicht aufgerufen weil er im C++ file steckt
und der Linker dann die weak Bindung nicht ersetzt. So sieht es besser
aus:
Hi Pascal,
Ich hab mal in dein ELF geschaut und jetzt auf den ersten Blick nichts
gob falsches gefunden. Sektionen und Adressen sind soweit okay, Stack
stimmt auch.
Mal eine ganz allgemeine Frage: Unter welchem Betriebssystem willst Du
das denn zum Laufen bringen?
Unter Linux könnte ich Dir dort mit einem fertigen Paket weiterhelfen.
Und: Bist Du an GCC 5.3 gebunden oder hast Du freie Auswahl im Compiler.
Ich erinnere mich, das ich mit neueren Versionen auch so meine Probleme
hatte. Die währen zwar sicher lösbar gewesen, aber es war einfacher auf
eine alte Version zurückzugehen. Von der Code Qualität macht das beim
Cortex-M3 eh nicht so den Unterschied.
Gruß,
Nils
Hey,
@Jojo
also mit extern "C" wird der SysTick_Handler angesprungen :)
funktioniert jetzt wie gewollt.
War das erste mal dass meine main in einer .cpp steckt ... dachte das
waere vollkommen egal. Weil den Einsprungpunkt also die main function
hat er ja auch gefunden. Kann ich dem Linker das iwie sagen dass er auch
in den .cpp files suchen soll?
Was ist diese MBED Lib eigentlich? Habe mir das angeschaut verstehe aber
nicht was es mir jetzt bringt.
@Nils:
Mein Build System ist Arch Linux, also immer recht aktuell im repo ->
was natuerlich auch zu Probleme fuehrt, klar ;)
Pascal H. schrieb:> Was ist diese MBED Lib eigentlich? Habe mir das angeschaut verstehe aber> nicht was es mir jetzt bringt.
Das ist ein C++ Abtraktionslayer um die üblichen Standard Peripherals,
die Cortex-M3 CPUs so haben. Sie ist wirklich einfach zu benutzten und
auch gut getestet.
Nachteil ist ein höherer Codesize Footprint sowie der übliche Laufzeit
Overhead, den so ein Abstraktionslayer so mitbringt. Auch sind
Spezialfeatures vieler Peripherien nicht unterstützt. Deine SPI
Schnittstellen z.B. können auch TI-SSP. Sowas wird nicht unterstützt
weil es schon recht speziell ist
Vorteil ist, das der Code - solange Du bei mbed bleibst - auch auf
vielen anderen CPUs läuft und man schnell mal was zusammencoden kann.
Ist toll für's Prototyping.
Wenn Du nichts von mbed benutzt, dann kostet es Dich auch nichts. Ist
alles optional und sehr modular. Einzig Timer0 wird von der API belegt.
Gruß,
Nils
Pascal H. schrieb:> Kann ich dem Linker das iwie sagen dass er auch> in den .cpp files suchen soll?
Da die Funktion SystickHandler nicht static deklariert ist wird sie als
public exportiert und der Linker findet diese auch. Die Tücke ist nur
das es in C++ ein 'name mangling' gibt, da werden die Funktionsnamen
dekoriert damit Funktionen mit gleichem Namen aber unterschiedlichen
Argumenten unterschieden werden können. Ohne das extern "C" findet der
Linker ein _SystickHandler und ersetzt damit nicht den default aus dem
Assembler Startupcode.
mbed ist eine Online Entwicklungsumgebung. Die Website ist nicht gerade
übersichtlich weil es jetzt eine Weiterentwicklung gibt die aber nicht
richtig voran kommt. Rechts oben gibt es einen Verweis auf die alte
'Classic Developer' Umgebung. Da kann man sich registrieren und einen
Online Compiler nutzen. Das ist besonders einfach für Boards die 'mbed
enabled' sind, dafür gibt es dann angepasste Libs und die Boards haben
üblicherweise auch den Programmer on Board dabei und man braucht nur ein
USB Kabel um loszulegen.
Die Lib ist quelloffen und auf github gehostet, das ist die mbed-master.
Wenn man mit dem gcc arbeiten möchte gibt es die Variante gcc4mbed, die
installiert eben die gcc toolchain und man hat mit Null Aufwand die
Möglichkeit Projekte in der Kommandozeile mit make zu bauen. Das MiniDK2
ist dem LPC1768 mbed Ur-Board ähnlich (incl. Ethernet), man kann also
auch ein Projekt in der Online Umgebung starten und das für den gcc
exportieren. Soweit ich weiss gibt es aber für das MiniDK2 angepasste
Libs, es ist nur kein offizielles mbed Board und nicht in der mbed
Platform Liste.
Die mbed API ist C++, intern werden low level Funktionen in C verwendet,
wie z.B. die GPIO die du verwendet hast. Mit dem genannten gcc4mbed
benutzt man dann die DigitalIO Objekte:
Hey Jojo,
danke fuer die ausfuehrliche Erklaerung ;)
Klar finde ich die Idee hinter mbed nicht schlecht, dennoch moechte ich
gerne so viel wie moeglich zu fuss selber machen um tiefere Einblicke zu
erhalten.
D.h. ohne extern "C" gibt es nur die _SysTick_Handler, da keine weitere
"SysTick_Handler" mit anderen Argumenten existiert. Wenn ich jetzt also
im Assembler Startup Code das Symbol auf _SysTick_Handler aendern wuerde
dann koennte ich das extern "C" weglassen?
Ich habe irgendwo mal gehoert es gaebe eine LPC17xx_Startup.cpp, damit
haette ich dann nicht dieses Problem. Leider habe ich im mbed repo keine
cpp startup Sachen gefunden fuer den GCC. Nur in Code Red oder
codesourcery.
in deinem Beispiel benutzt du keine C++ Features, du kannst also deine
.cpp files nach .c umbenennen. Ansonsten ist das extern "C" der übliche
Weg bei dem Mix aus C/C++, ist also nix ungewöhnliches.
Den Startupcode kann man auch in C schreiben, Assembler ist wohl
historisch begründet durch die älteren ARM die zwei Befehlssätze hatten.
hier ist ein Startupcode in cpp, für CodeRed Umgebung aber müsste auch
im gcc laufen:
https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC176X/TOOLCHAIN_GCC_CR/startup_LPC17xx.cpp
wenn du nicht mbed benutzt kannst du auch den Offset in der RAM section
weglassen:
statt
RamLoc32 (rwx) : ORIGIN = 0x100000C8, LENGTH = 0x7F38 /* 32k */
geht
RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
mbed kopiert die Interrupt Vector Table ins RAM, das ist eine Falle wenn
man die lib in einer IDE mit automatisch generiertem Linkerfile
benutzt...
Hi Pascal,
So, ich hab mir jetzt auch mal einen Account gemacht (bin ex:
Nils(gast))
Schön das es jetzt alles bei Dir läuft. Gratulation. War ja fast schon
eine Zangengeburt.
Wenn Du fragen zum LPC1768 hast, dann schreib mich gern an, ich kann
sicher hier und da tips geben, da ich mittlerweile ein gutes Jahr
Erfahrung mit dem Teil habe und schon so manche Probleme gelöst habe.
Ich freue mich auch darüber, über weitere Quirks von diesem Chip zu
erfahren.
/Nils
Hey vielen Dank Nils, ich werde darauf zuruekkommen ;)
Ich habe noch eine Frage bezueglich gcc und newlib.
Angenommen ich wuerde newLib nano verwenden wollen um system spezifische
implementierungen zu haben (File -> printf usw.), dann stelle ich bei
den linker options --specs=nano.specs ein.
Dann fehlen aber einige references ...
Diese muss ich dann selbst implementieren oder?
z.B. in einer syscalls.c
#################
EDIT 1
Ok ich habe die sys.cpp aus dem mbed repo TOOLCHAIN_GCC_CS verwendet.
Funktioniert :)
Ich weis zwar nicht genau was diese syscalls tun aber es geht.
Ich weis nur dass _sbrk fuer malloc benoetigt wird. Dh. malloc will
Speicher reservieren und fraegt uber _sbrk den naechsten Heap Pointer an
bzw. wo der Heap steht? Warum + 7 und diese verunden mit 7 nicht?
Was waere wenn ich dieses syscalls nicht habe also --spec=nosys? Dann
funktioniert malloc nicht, ok, aber es muss doch trotzdem speicher
reserviert werden. Wer weis denn dann wo der Heap Pointer steht?
Ok das macht sinn :)
Da ich jetzt sowieso cpp verwende, wollte ich gerade mal schnell ein
#include <iostream> mit std::string test("test"); in meinem Programm
schreiben.
Leider laeuft das Programm jetzt nicht mehr los wenn ich es flash.
Und ich glaube ich weis auch warum. Ohne #include <iostream> ist das
Programm 132K gross.
Mit iostream ist es 928K gross !! so viel Platz hab ich doch gar nicht
...
Dh. ich sollte mir das mit iostream ganz schnell aus dem Kopf schlagen?
arm-none-eabi-size ${BuildArtifactFileName}
Pascal H. schrieb:> Dh. ich sollte mir das mit iostream ganz schnell aus dem Kopf schlagen?
ja, definitiv. Ein Zitat von einem Kommentar auf Stackoverflow.com:
'iostream adds cin, cout and cerr, which pulls in everything but the
kitchen sink'.
In C++ auf dem µC sollte man ausserdem RTTI und Exceptions nicht
benutzen, deshalb die Optionen '-fno-rtti -ffunction-sections
-fdata-sections -fno-exceptions -fno-delete-null-pointer-checks
-fomit-frame-pointer' hinzufügen.
Um die Codegrösse anzuzeigen (text segment):
arm-none-eabi-size output.elf
> Ohne #include <iostream> ist das> Programm 132K gross.
Das ist auch schon viel zu gross, meinst du wirklich die text size? Die
Grösse vom .elf ist uninteressant, da sind auch die Debug Infos drin.
Mit den Optimierungen komme ich für die Debug Version auf 4388 Bytes,
ohne Debug werden es nur 1700 Bytes.
Hallo jojos,
ja ich hatte einfach mit "du -s TestMBED.elf" die komplette grosse
genommen.
Ich habe die von dir genannten flags verwendet und komme auf eine grosse
von 2660 bei der text section im Release mit maximaler Optimierung.
für den Linker gibts ne andere Option für die sections, -flto -Os, dann
wird es vielleicht noch etwas kleiner. Was bei deinen 512 kB Flash aber
nicht unbedingt nötig ist :-)