Hallo,
ich unternehme gerade meine ersten Gehversuche mit dem LPC1788 und
nachdem nun die LED blinkt und die Dummy-Text UART Ausgabe
funktionieren, habe ich paar andere Probleme:
Problem 1) Gibt es ein Tool, welches mir die Startup-Variablen "bequem"
ausrechnet ? In der system_LPC177x_8x.c steht etwas von "Use
Configuration Wizard in Context Menu" - aber wo ?!!!
Ich würde gerne die CPU mit 25Mhz ext. Quarz betreiben und diese mit
100Mhz intern betreiben. Momentan verwende ich folgende Config,
allerdings wird dort der interne 12Mhz Quarz verwendet.
#define CLOCK_SETUP 1
#define SCS_Val 0x00000031 // 0x00000021
#define CLKSRCSEL_Val 0x00000000 // Use Internal Clk = 0,
External = 1
#define PLL0_SETUP 1
#define PLL0CFG_Val 0x0000000C
#define PLL1_SETUP 0
#define PLL1CFG_Val 0x00000023
#define CCLKSEL_Val 0x00000101
#define USBCLKSEL_Val 0x00000201
#define EMCCLKSEL_Val 0x00000001
#define PCLKSEL_Val 0x00000005
#define PCONP_Val 0x0000A28E // 0x042887DE
#define CLKOUTCFG_Val 0x00000000 // 0x00000100
Problem 2)
Woher kriege ich das ld-script ? Die CodeRed Umgebung erzeugt zwar ein
automatisches LD-Skript, aber ich habe Probleme mit 64bit Integer. Dort
stürzt die CPU ab. Nach div. Recherchen habe ich nun rausgefunden, dass
im LD-Skript etwas angepasst werden muss. Aber was ?!!
Gibt es ein Tool, der mir das ld-script erzeugt ? (Ist die Datei, die
mit -T "xy" im Makefile angegeben ist).
Problem 3)
Beim benutzen von sprintf erhalte ich folgende Meldung:
/usr/local/lpcxpresso_4.2.0_224/lpcxpresso/tools/bin/../lib/gcc/arm-none
-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb/libc.a(lib_a-sbrkr.o):
In function `_sbrk_r':
sbrkr.c:(.text+0xc): undefined reference to `_sbrk'
Google-Suche ergibt div. Lösungen, einmal wird eine leere _sbrk
definiert, dann gibt es sowas usw.
caddr_t _sbrk_r (struct _reent *r, int incr)
{
( void ) r;
( void ) incr;
return 0;
}
Ich vermute, sbrk pusht Daten auf dem Stack, vondaher denke ich, dass
eine leere sbrk nicht die Lösung des Problemes sein kann.
Vielen Dank schonmal im vorraus!
Tobias Neumann schrieb:> Die CodeRed Umgebung erzeugt zwar ein> automatisches LD-Skript, aber ich habe Probleme mit 64bit Integer. Dort> stürzt die CPU ab. Nach div. Recherchen habe ich nun rausgefunden, dass> im LD-Skript etwas angepasst werden muss. Aber was ?!!
Dann poste bitte das erzeugte ld-Script, und bitte auch die Quellen, die
besagen, dass man für 64-Bit-Integer das ld-script verändern soll.
Wofür benötigst Du 64-Bit-Integer?
Tobias Neumann schrieb:> Beim benutzen von sprintf erhalte ich folgende Meldung:
Ob es Dir hilft, weiß ich nicht, aber ich hatte vor einiger Zeit
ähnliche Probleme, vor allem beim "printf retarget". Nach einigen
Debug-Sessions umd Herumsuchen habe ich mir die benötigten Funktionen
selbst geschrieben.
Selbst wenn Du das zum Laufen kriegst, bleibt die Frage, ob dieses
sprintf mit 64-Bit-Integer umgehen kann ...
Hi,
die 64bit integer werden von lpc177x_8x_uart.c für uart_set_divisors
verwendet (CMSIS v2 - . Ich habe jetzt die uart_set_divisors aus einer
älteren CMSIS übernommen, wo uint32 verwendet wird und es geht.
Hier der Link zur CMSIS mit 64bit uints:
http://ics.nxp.com/support/documents/microcontrollers/zip/lpc177x.lpc178x.cmsis.driver.library.zip
Ich weiss leider nicht mehr, in welchem Kontext ich den Beitrag gefunden
habe. Dort stand, dass der Eintrag .ARM.exidx modifiziert werden sollte.
- Kannst du bei dir 64bit operationen durchführen ?
unsigned char i;
uint64_t a;
for (i=0;i<5;i++) {
a = i*10;
delay (a);
}
Sobald ich 64bit einsetze, steigt der prozessor nach der Multiplikation
aus.
Ändere ich die Datentypen auf uint32_t ab, ist alles in Ordnung.
Ich denke es ist besser, für printf und Kollegen schreibt man sich was
kleines selber oder nimmt eine der vielen kleinen Implementierungen.
Wenn es nicht dringend nötig ist, würde ich auf die syscall.c -
Geschichten verzichten. Damit ist es auch wesentlich leichter mal den
Compiler zu wechseln.
die 104 Bytes abzuziehen dürfte unnötig sein, der Stack wächst doch nach
unten. In den CR .ld ist der Stack auch als __top - 0 definiert.
Gibt es da noch includes wo die absoluten adressen der Speicherbereiche
definiert sind? Das fehlt wenn ich das mit den CR .ld vergleiche.
nagut, kann ich so nicht verwenden. ich hab die datei übrigens doch
gefunden, wird auch miteingebunden.
ich weiss langsam echt nicht mehr weiter. habe jetzt auch mal das
gesamte projekt hier mal angehängt, ich verstehe nicht, wo der fehler
ist.
das komische ist auch, dass wenn ich die sprintf-routine einbinde, der
code plötzlich von 4kb -> 30kb aufgebläht wird.
vor dem sprintf() ist noch ein while(1), damit dürfte dein Programm
garnicht zum sprintf kommen (wenn du nicht mit dem Debugger nachhilfst),
das meinst du hoffentlich nicht mit 'abschmieren' ?
Und das printf den Code stark aufbläht ist richtig, es gibt bei den CR
Beispielen auch einen schlanken Ersatz. Aber bei 512k Flash sollten die
26kB doch nicht wehtun.
in "stdint.h" stehen die format specifier, %lli, %lld und %llx gibts
auch noch. Auch das printf() mit der Semihost-Lib funktioniert mit den
long longs.
Compiliert mit der NXP CodeRed, läuft auf dem LPC1769.
Jojo S. schrieb:> Compiliert mit der NXP CodeRed, läuft auf dem LPC1769.
Welcher GCC ist das? Mit welcher Optimierung?
Könntest Du bitte in Deiner Version eine Division einbauen und den Part
posten, in welchem die Division aufgerufen wird?
1
ull /= 10
Bei mir erzeugt der "arm-none-eabi-gcc (Linaro GCC 4.5-2011.02-0) 4.5.2"
mit -Os bei der uint64 Division ein "blx":
wo siehst du denn eine end-los while-schleife vor der ausgabe ?!
die while-schleife beinhaltet den kompletten code (led toggle und
sprintf).
ich hab mir jetzt auch die neueste code-red heruntergeladen, gcc 4.5.2.
hast du das makefile in meinem archiv mal ausgeführt ?
mit -O0 erzeugt der mir diesen code:
movw r0, #:lower16:.LC2 @,
movt r0, #:upper16:.LC2 @,
ldrd r2, [r7] @, ll
bl printf @
.loc 2 119 0
ldrd r2, [r7, #16] @ tmp167,,
mov r0, r2 @, tmp167
mov r1, r3 @,
mov r2, #10 @,
mov r3, #0 @,
bl __aeabi_uldivmod @
mov r2, r0 @ tmp170,
mov r3, r1 @,
strd r2, [r7, #16] @ tmp170,,
.loc 2 120 0
movw r0, #:lower16:.LC3 @,
movt r0, #:upper16:.LC3 @,
gibt es eigentlich irgendeine andere quelle ? Ich brauch nur ein
dementsprechendes makefile und paar beispiele mit dem jeweiligen
startup-code.
von codered bin ich momentan wirklich verdammt enttäuscht.
ok, das while(1) sah nur hier im Editor komisch eingerückt aus.
Dann benutzt du die libcr_, also die CodeRed Lib, da sollte auch das
_REDLIB_ define benutzt werden. Im Startcode wird dadurch zB __main()
statt main() aufgerufen, evtl. fehlen dann Initialisierungen.
Hast du sonst keine Debugmöglichkeit? LPCLink? Ohne JTAG/SWD würde ich
mich nicht an den Cortex-M3 wagen, das ist ganz schön mühselig.
Das CR Zeug gefällt mir schon ganz gut, es ist leider nur teuer. Und
wenn du es schon runtergeladen hast, erstelle doch damit ein kleines
Projekt und vergleiche.
Tobias Neumann schrieb:> Hängt aufjedenfall mit der gelinkten lib zusammen. Mit diesem ld-script> funktioniert sprintf.> Im Makefile muss beim linken dann aufjedenfall die option "-nostdlib"> angegeben werden.
Aus dem Makefile von test.zip
Da war "-nostdlib" schon enthalten?!
Es fehlt m. E. bei den LDFLAGS die Option "-mcpu=cortex-m3". Wie man
sieht, ist im "echo" davor diese Option durch die CFLAGS indirekt
enthalten. Wen will der Verfasser damit verwirren?
In meinem Makefile war das gleiche Problem (fehlendes -mcpu in LDFLAGS),
und es scheint nicht aufzufallen, solange man keine 64-Bit-Operationen
durchführt. Vermutlich linkt er ohne die korrekte -mcpu-Angabe gegen die
ARM32-libs. Die "blx" sind bei mir nun auch verschwunden.
Nun funktionieren 64-Bit-Operationen.
Jungs, Ihr seid Einsame spitze. Daumen hoch und vielen Dank an alle!
Ich hab leider nur die UART-Schnittstelle als Debugmöglichkeit, da ich
die CPU bereits in meinem eigenen Design drin habe.
CodeRed ist aus meiner Sicht der letzte Mist und verfehlt den Sinn
"auspacken, installieren, loslegen". Allein diese Eclipse-Umgebung ist
ein
Krampf. Wer mit Emacs und Makefiles aufgewachsen ist, der dreht sich bei
solchen Editoren im Grab um - und dann soll man da auch noch Geld für
zahlen...
Das 64bit Problem ist nun durch die LDFLAGS-Erweiterung der mcpu auch
behoben, DANKE!!! :)
"-nostdlib" hatte ich zum testen in der Zwischenzeit entfernt gehabt,
aber das muss aufjedenfall mit rein.
Anbei das "bereinigte" Makefile und die startup.ld - bei dieser
Konstellation wird kein sysconfig.c benötigt, da die richtigen libs
gelinkt werden.
Tobias Neumann schrieb:> Ich hab leider nur die UART-Schnittstelle als Debugmöglichkeit, da ich> die CPU bereits in meinem eigenen Design drin habe.
Mehr verwende ich in der Regel auch nicht. Ich würde auch sagen, dass es
mit Debugger in diesem Fall nicht einfacher gewesen wäre.
> CodeRed ist aus meiner Sicht der letzte Mist
Dem stimme ich schon zu, weil es sich nur als "root" installieren lässt
und zumindest in früheren Versionen z. B. libusb überschrieben hat.
> Wer mit Emacs und Makefiles aufgewachsen ist, der dreht sich bei> solchen Editoren im Grab um
Wieso wechselst Du dann? Du wirst lachen, ich verwende ausschließlich
Emacs und make. Ich schätze Eclipse für Java, aber mit "Makefile based
projects" und C/C++ bin ich 2x gescheitert.
> "-nostdlib" hatte ich zum testen in der Zwischenzeit entfernt gehabt,> aber das muss aufjedenfall mit rein.
Mit "-nostdlib" wird es nicht immer funktionieren. Bei der
Optimierungsstufe -Os wird gcc ab und zu memcpy oder memset einbauen.
Kann man aber auch selbst schreiben oder aus der newlib kopieren.
> Das 64bit Problem ist nun durch die LDFLAGS-Erweiterung der mcpu auch> behoben, DANKE!!! :)
Na also, geht doch :-)
gibt der gcc keine Warnung aus wenn so eine wichtige Angabe fehlt? Der
Fehler muss doch schon beim kompilieren, nicht erst beim Linken
enstehen, den 'blx' erzeugt doch der Compiler.
Der LPC ist mein erster ARM, da hatte ich die Hoffnung, dass die ersten
Gehversuche mit CodeRed einfacher wären, vorallem mit den
Startup-Skripts etc.
Das einzige, was ich jetzt noch verwende sind die CodeRed GCC/Tools, da
werde ich bei Gelegenheit auch den Kram runterschmeissen und auf bare
metal gcc umsteigen. Gibt es da irgendwelche Empfehlungen ? Momentan
weiss ich auch nicht, was die Vorteile der Libred sein sollen, habe da
newlib aktiv.
Könntest du das Problem mit memcpy bitte noch etwas genauer ausführen ?
@Jojo:
Der Assembler generiert bei mir auch kein "blx", sondern "bl", aber
trotzdem geht da dann irgendwas beim linken in die Hose, wenn die mcpu
dort nicht angegeben ist.
> @Jojo:> Der Assembler generiert bei mir auch kein "blx", sondern "bl", aber> trotzdem geht da dann irgendwas beim linken in die Hose, wenn die mcpu> dort nicht angegeben ist.
ja, sehe ich jetzt auch, ganz schön kompliziert... Zum kompilieren wurde
der mcpu switch doch schon benutzt. In den map files sieht man aber
Unterschiede, ohne die -mcpu wurden die 64 Bit Ops aus der 'thumb' lib
benutzt, mit -mcpu aus der 'thumb2'.
Eine Diskussion über die Tools passt in diesen Thread nicht gut rein,
das artet eh nur aus wg. IDE vs Kommandozeile oder Editor :-) Ich habe
zumindest mit der CR/LPCXpresso einen guten Einstieg gefunden, hat alles
auf Anhieb geklappt. Gut in der IDE muss man halt die Einstellungen
erstmal alle finden.
Das CooCox sieht noch brauchbar aus, allerdings sind die von den
Chinesen selbst geschriebenen Tools auch closed source und auf Fehler
oder Probleme reagieren die da sehr langsam.
Nur bei den schönen SWD Debugmöglichkeiten möchte ich wirklich kein
printf-Debugging mehr haben, das ist echt nicht state-of-the-art.
wg. der Lib:
http://support.code-red-tech.com/CodeRedWiki/RedlibAndNewlib
die Redlib ist wesentlich schlanker, in meinem Bastelprojekt macht das
85k zu 130k Codesize.
Den Startup Code finde ich auch sehr übersichtlich. Schwieriger ist eher
erstmal PLL und Power richtig einzustellen, da hilft die CMSIS schon.
Jojo S. schrieb:> gibt der gcc keine Warnung aus wenn so eine wichtige Angabe fehlt? Der> Fehler muss doch schon beim kompilieren, nicht erst beim Linken> enstehen, den 'blx' erzeugt doch der Compiler.
Nein, keine Warnung.
M. W. gibt es leider "Default-Werte" beim Compiler, Assembler und
Linker.
Beim Kompilieren sind die Div-Routinen extern, da gibt es keine Fehler.
Das Linken von "thumb" und "arm32" "object files" gemischt kann im Falle
von "interworking" durchaus Sinn machen. Bei Cortex-Mx natürlich nicht.
Vermutlich wirkt sich das "-mcpu" bei ld nur auf die Auswahl der zu
linkenden Library aus. Darüber hinaus gibt es zumindest für diesen Fall
keine Prüfung.
Die Sache mit dem "bl":
Das "blx" entstand nur bei mir, d. h. nicht mit einem GCC von Code Red.
Es ist in der Tat so, dass im .s noch ein "bl" steht (in beiden Fällen):
1
bl __aeabi_uldivmod
im .lss steht im Falle von "ohne -mcpu=cortex-m3"
1
aba: f002 e89e blx 2bf8 <__aeabi_uldivmod>
Wer kann das gewesen sein, wenn nicht der Linker?
Jojo S. schrieb:> Der Unterschied dürfte sein das der gcc mit anderen Voreinstellungen> compiliert wurde (oder woher kommen die?). Setze mal die Flags> '-save-temps' in das Makefile, dann bleibt das main.s stehen. Da steht> bei mir im Kopf drin:
Da ist bei mir leider nix drin, schade eigentlich. Es ist der GCC aus
"summon-arm-toolchain".
Tobias Neumann schrieb:> Der LPC ist mein erster ARM, da hatte ich die Hoffnung, dass die ersten> Gehversuche mit CodeRed einfacher wären, vorallem mit den> Startup-Skripts etc.
Der guten Ordnung halber, es war ein Sammelsurium aus uint64, einer
fehlenden Option im Makefile für den Linker, und einer nicht vorhandenen
Prüfung im Linker. Kam das 64-Bit-CMSIS im Paket mit Code Red oder
separat? Ich wage zu behaupten, es lag weder am Startup noch am Linker
Skript.
Tobias Neumann schrieb:> und auf bare> metal gcc umsteigen. Gibt es da irgendwelche Empfehlungen ?
Bis zu diesem Thread hätte ich uneingeschränkt "summon-arm-toolchain"
empfohlen, da diese auch den Cortex-M4 mit FPU unterstützt.
Zwischendurch wollte ich die uint64-Thematik auf dem stm32f407 (CM4 mit
FPU) testen. Dort weigert sich der Linker, weil er für die
Parameterübergabe der 64-Bit-Variablen über die VFP-Register eine
separate multilib benötigt.
Vermutlich gibt es kein größeres Interesse, siehe:
https://github.com/esden/summon-arm-toolchain/issues/14
Ich teste gerade den "fork", aber die Existenz dieses "forks" ist etwas
unschön.
> Momentan> weiss ich auch nicht, was die Vorteile der Libred sein sollen, habe da> newlib aktiv.
Generell bin ich über folgende Punkte gestolpert
- Es ging nicht (printf retargeting)
- Es bläht den Code auf
- Es benötigt Puffer (sprintf - schlecht auf attiny/msp430g)
- Es ist nicht portabel (8-Bitter, 16-Bitter, 32-Bitter:AVR - MSP430 -
ARM/PIC32/Renesas RX)
- Es gibt Lizenzthemen im weitesten Sinne
Wie schon geschrieben, ich habe mir alles selbst geschrieben. Das Zeugs
läuft also vom kleinen attiny bis zu den "großen" 32-Bittern. Seitdem
ist Ruhe im Karton.
Tobias Neumann schrieb:> Könntest du das Problem mit memcpy bitte noch etwas genauer ausführen ?
Manche "Massen-Initialisierungen" von Variablen/Arrays schreibt der GCC
um. Statt irgendwelcher Einzelzuweisungen kopiert er dann per memcpy
einen ganzen Bereich in die Zielvariablen. Soweit zumindest mein
Verständnis.
Tobias Neumann schrieb:> aber> trotzdem geht da dann irgendwas beim linken in die Hose, wenn die mcpu> dort nicht angegeben ist.
Tja, "Operation gelunden - Patient tot". Das Linken an sich ist
erfolgreich, es kommt zur Laufzeit zu einer "undefined instruction".
Wobei zu klären ist, wo das "blx" gesehen wurde: Wie schon oben
geschrieben, bei mir tauchte es erst im ".lss" auf, also dem Listung,
welches aus der .elf generiert wurde.
Ohje...
hab noch eine letzte frage, ich würde gerne die cpu mit volle Leistung
betreiben. Werde allerdings nicht wirklich schlau.
Ich hab mittlerweile auch die XLS von NXP (siehe link von Jojo), weiss
allerdings nicht richtig mit dem Teil umzugehen.
FIn = 25Mhz
Inwiefern ist jetzt Fcco wichtig, bzw: was muss ich dort eintragen, wenn
ich auf 120mhz auftakten möchte ?
Wenn ich im Max-Cpu Feld 120 eintrage, dann ist es ein ungültiger Wert.
Kann mir das bitte jemand erklären, bzw: mir einfach die Werte für die
Initialisierung für 120Mhz Systemtakt bei 25Mhz Fin geben ?
Das xls ist vielleicht noch aus der Zeit bevor es die 120 MHz CPUs gab,
die meisten aus der Serie laufen ja 'nur' bis 100 MHz.
Gültige Werte wären: Fcco=480 MHz bei Fin=25MHz.
Eingestellt werden muss dann der CPU Divider=4, M=48, N=5. Das Fcco von
480 MHz damit man auch einen passenden Clock für USB hat, da kann man
dann auch PLL0 verwenden und den USB Teiler von 10 einstellen.
Das Ganze ergibt sich leider nur aus Querlesen von Datenblatt, diesen
Excelsheet und Beispielen...