Hallo,
ähnlich wie beim ARM7TDMI werden die Cortex M3 ja von verschiedenen
Herstellern lizensiert und zusammen mit ihrer eigenen Peripherie als
kaufbare Microcontroller produziert.
Gibt es irgendein Hersteller, dessen Peripherie und Support besonders
gut ist?
Mir ist klar, dass es hierzu viele Meinungen gibt, aber genau die würden
mich interessieren, um eine Entscheidung zu finden.
Vielen Dank im Voraus!
Grüße,
Gast
STM32F10x in Verbindung mit CMSIS würde ich empfehlen. Läuft
super-stabil, recht simpel zu programmieren, und es gibt Tonnen von
Examplecode.
My Prefered IDE: uVision4 :-)
Simulation (Core + Peripherals), ULINK/2/ME und J-Link.
VG,
/th.
Es gibt zwar inzwischen einige Cortex-M3 Derivate verschiedener
Hersteller, aber ich denke es haben sich 2 Hersteller am Markt
etabliert. Zum einen ist das ST mit den STM32F10x und zum zweiten
NXP/Philips mit den LPC17xx. Ich habe mit beiden gearbeitet, bevorzuge
jedoch derzeit die LPC17xx, da sie gegenüber den neueren STM32F105/107
unschlagbar im Preis- Leistungsverhältnis sind und nahezu dieselbe
Peripherie bieten. Außerdem hat sich ST mit fehlerhaften Bootloadern in
der neuen Generation selber ins Abseits katapultiert. Das soll zwar bei
den neuen Versionen beseitigt sein, aber man weiß derzeit nie, welche
man geliefert bekommt.
Zur Programmierung dieser Controller muß man sicher nicht teure
Entwicklungssysteme kaufen, die "Random" vorgeschlagen hat. Zum Anfang
(und sicher auch für später) tut es auch die freie Version des
C-Compiler G++ von Codesourcery. Als Editor kann man so ziemlich alles
nehmen, ich bevorzuge den UltraEdit32. Wer eine kostenlose IDE will, für
den ist Eclipse sicher die erste Wahl.
Ob man einen Simulator und Debugger braucht, muß jeder selbst
entscheiden. Ich brauchs nicht, zum debuggen gebe ich mir Daten über
einen seriellen Port aus.
Zur Programmierung beider Serien ist kein JTAG-Adapter notwendig, es
reicht bei beiden eine serielle Schnittstelle, bzw. ein
USB/Seriell-Interface und das zum Controller passende Programmiertool,
das in beiden Fällen kostenlos zu bekommen ist.
Ob man die Library CMSIS benutzt, muß auch jeder selber entscheiden.
Natürlich ist die Programmierung hierdurch recht einfach, da man sich
nicht in die Tiefen der Registerprogrammierung einarbeiten muß. Aber ich
bin der Meinung, daß diese den Code nur unnötig aufbläht und damit
natürlich unnützerweise langsam macht. In meinen Sourcen fimndet man
deshalb keinerlei CMSIS, das Ergebnis ist ein kompakter und schneller
Code.
Natürlich gibt es auch noch Cortex-M3 von anderen Herstellern wie Texas
Instruments (vormals Luminary Micro), Atmel (AT91SAM3) und einigen
Anderen. Einige haben den Markteinstieg verpaßt oder richten sich an
andere Zielgruppen. Mit den Controllern von ST und NXP kannst du auf
längere Sicht nichts verkehrt machen.
Erwin
Erwin Reuss schrieb:
> Ob man die Library CMSIS benutzt, muß auch jeder selber entscheiden.> Natürlich ist die Programmierung hierdurch recht einfach, da man sich> nicht in die Tiefen der Registerprogrammierung einarbeiten muß. Aber ich> bin der Meinung, daß diese den Code nur unnötig aufbläht und damit> natürlich unnützerweise langsam macht. In meinen Sourcen fimndet man> deshalb keinerlei CMSIS, das Ergebnis ist ein kompakter und schneller> Code.
In dem Punkt muss ich dir wiedersprechen. Wenn ich CMSIS meine, meine
ich im wesentlichen die core_cm3.c/.h.
In der c-datei sind intrinsic standards abgebildet, die dann über
armcc/iarcc/gcc gleich funktionieren, interessant ist aber die
core_cm3.h.
Dort sind ein haufen inline funktionen drin, die exact das machen, was
man an deren stelle in den code schreiben müsste.
Das bläht absolut nix auf. Ich selbt bin überhaupt kein Fan von
driverlibs, aber mag durchaus schlanke kleine helferlein.
Hier wird der NVIC (ein recht komplexes peripheral, was bisher die
wenigsten verstanden haben) auf einen Satz einfacher Funktionen
abstrahiert, die jeweils nur ein Register addressieren. (btw: Ich kenn
den Core weil ich den entworfen und geschrieben hab ^^*grins*^^).
Beispiel 1 (Interrupt enable):
SCB->SHP[((uint32_t)(IRQn)&0xF)-4]=((priority<<(8-__NVIC_PRIO_BITS))&0xff);}/* set Priority for Cortex-M3 System Interrupts */
5
else{
6
NVIC->IP[(uint32_t)(IRQn)]=((priority<<(8-__NVIC_PRIO_BITS))&0xff);}/* set Priority for device specific Interrupts */
7
}
Wenn man verstanden hat, wie der NVIC funktioniert, erschliesst sich
einem die Funktionsweise dieser beiden Beispiele sofort. Ist einem das
noch nciht bekannt, rätzelt man mindestens ne Stunde über die beiden
obigen Funktionen und das warum :-)
Der Unterschied ist, dass - nicht, wie bei DLs üblich - irgendwelche
undurchsichtigen Monsterfunctions irgendwas magic-mässiges machen,
sondern dass hier wirklich mal sinnvoll abstrahiert wurde.
Wenn hier irgendetwas fehlt, kann man problemlos einen Registerzugriff
"manuell" hinterherschieben, ohne doppelten und somit langsameren Code
zu haben.
Mein Ansatz war damals: Eine funktion (inline) per Register. Das lässt
sich auf multiple Instanzen von Peripherals (z.B. GPIO) durch die
übergabe der Pointer sehr einfach realisieren:
1
PortOut(GPIOA,data);
Damit hätte man eine sinnvolle Lib für Registerliebhaber. Leider liess
sich das nur für den Core durchsetzen.
Die SysInit ist sicher zum Einstieg sinnvoll, was es an Sonderfunktionen
sonst noch gibt entzieht sich z.Zt. meiner Kenntnis, da ich nur den
Cortex-M3 Core der CMSIS pflege.
Schau da ruhig mal rein!
VG,
/th.
Erwin Reuss schrieb:
>> Natürlich gibt es auch noch Cortex-M3 von anderen Herstellern wie Texas> Instruments (vormals Luminary Micro)
Gerade Luminary hat massig Anschlussmöglichkeiten und dürfte durch den
Aufkauf durch TI auch längerfristig Zukunft haben.
Muss zustimmen. Verwende auch die CMSIS-Library. Der Unterschied ist
zwischen selbst schreiben und CMSIS minimal (zugunsten CMSIS ;) ). Habe
aber auch nicht lange dann manuell rumgemacht :D
Ansonsten kann ich auch, wie Erwin die LPC-Serie empfehlen. Wir hatten
mit den gleichen Problemen beim ST F107 zu kämpfen :)
Der LPC1768 funktioniert wirklich wie er soll.
Von ST kannst aber zum Beispiel die älteren F103 nehmen. Maßenweise
beispielcode für. Aber USB und CAN gehen nicht gleichzeitig, weswegen
sie für mich nicht in Frage kamen.
LM bzw. jetzt TI war deutlich langsamer, deswegen gleich der Griff zum
NXP.
Schöne Grüße aus Stuttgart
Bisher scheinen mich die LPCs eher zu überzeugen. Vor allem das
Preis-/Leistungsverhältnis scheint erstaunlich gut zu sein.
Einen LPC1751 kriegt man sogar bei Farnell für 3,50eur und der hat
schon USB.
Hört sich gut an! Und USB ist ein absolutes Muss für mich, da ich
mittlerweile keinen einzigen PC mehr habe, der eine serielle oder
parallelle Schnittstelle hat und ich auch keinen 3,50EUR teuren FT232
verwenden möchte.
Der einzige Kritikpunkt scheint das 80pinnige Gehäuse zu sein. Hatte auf
etwas mit 48pins gehofft, weil Platz auch oft viel Geld kostet.
Kennt jemand sowas wie den LPC1751 in etwas kleinerer Bauform?
Grüße,
Gast
Random ... schrieb:
> In dem Punkt muss ich dir wiedersprechen. Wenn ich CMSIS meine, meine> ich im wesentlichen die core_cm3.c/.h.
So sieht das nur auf den ersten Blick aus. ARM selbst definiert den
Begriff CMSIS nämlich für beides, sowohl das was ARM unabhängig von der
Implementierung bieten kann, als auch für den herstellerabhängigen Teil
mit Periphieriedefinitionen und ggf. Support-Funktionen. Siehe
http://www.onarm.com/download/download378.asp.
> Dort sind ein haufen inline funktionen drin, die exact das machen, was> man an deren stelle in den code schreiben müsste.
Nur dass viele dieser Funktionen in core_cm3 leider eben nicht inline
sind, sondern für einen einzige Assembler-Befehl eine Funktion
aufgerufen wird. Das Zeug gehört Inline in die core_cm3.h, nicht als
Einzeiler in core_cm3.c. Mindestens bei GCC, inwieweit andere Compiler
Inline-ASM können weiss ich nicht. Ist leider auch noch buggy
(ldrex/strex mit Registerkonflikt).
A. K. schrieb:
> Nur dass viele dieser Funktionen in core_cm3 leider eben nicht inline> sind, sondern für einen einzige Assembler-Befehl eine Funktion> aufgerufen wird. Das Zeug gehört Inline in die core_cm3.h, nicht als> Einzeiler in core_cm3.c. Mindestens bei GCC, inwieweit andere Compiler> Inline-ASM können weiss ich nicht. Ist leider auch noch buggy> (ldrex/strex mit Registerkonflikt).
das ist eigentlich so weit wie möglich inline gemacht, nur an einigen
stellen mochter der compiler das nicht. Diese "Reste" sind in der .c zu
finden. In der .h sind viele Intrinsics auch als #define oder inline
gelöst.
Vielleicht hat sich ja z.B. am gcc was geändert, so dass es
funktioniert.
Ich würde am liebsten komplett auf die core_cm3.c verzichten, aber z.Zt.
gehts leider nciht ohne dieses vehikel.
VG,
/th.
PS: Wenn du was findest - her damit. Wird umgehend geändert. Kochen
schliesslich alle nur mit Wasser :-)
Random ... schrieb:
> das ist eigentlich so weit wie möglich inline gemacht, nur an einigen> stellen mochter der compiler das nicht.
Im CMSIS V1.0 von ARM sind allerlei nützliche Einzeiler wie
__set_BASEPRI im .c File, nicht im .h File.
> Diese "Reste" sind in der .c zu finden.
Ich wüsste beim GCC nicht, warum man das in .c reinpacken muss. Wenn der
Assembler mal über STREX stoplern sollte, dann ist nicht der Compiler
schuld, sondern die fehlerhaften "=r" an Stelle der korrekten "=&r", die
den Compiler dazu bewegen können, das Adressregister zu recyceln, was
der Befehl nicht so mag.
Ich habe den ganzen Kram sofort dorthin verfrachtet wohin er gehört (mit
"static inline" verziert).
> Ich habe den ganzen Kram sofort dorthin verfrachtet wohin er gehört (mit> "static inline" verziert).
magst mir das ma schicken (pm) oder hier ins forum stellen?
Ich würde dafür sorgen, dass es in die nä. Version der CMSIS kommt.
VG,
/th.
A. K. schrieb:
> Random ... schrieb:>> das ist eigentlich so weit wie möglich inline gemacht, nur an einigen>> stellen mochter der compiler das nicht.>> Im CMSIS V1.0 von ARM sind allerlei nützliche Einzeiler wie> __set_BASEPRI im .c File, nicht im .h File.
Beim ARM Compiler wird der Thumb-2 Befehlssatz nicht vom Inline
Assembler unterstützt. Stattdessen werden uns Compiler Intrinsics
nahegelegt. Ist auch prinzipiell besser, nur leider hat man "named
register variables" noch nicht für alle Register implementiert.
>> Diese "Reste" sind in der .c zu finden.>> Ich wüsste beim GCC nicht, warum man das in .c reinpacken muss.
Dar war Thorsten zu faul, das für GCC per #ifdef in der header Datei zu
implementieren :-)
Gruß
Marcus
http://www.doulos.com/arm/
das ist so nicht ganz richtig, und auch nicht fair.
Als das implementiert wurde, habe ich schon versucht, alles in das
headerfile zu packen, aber sobald parameter dazukamen, sträubte sich der
gcc, es gab Probleme. Hatte mit AAPCS (gcc macht die ganze
Registerzuordnung selbst, daher stehen in dem ASM kram ja auch variablen
drin und keine Register) zu tun, Problem war die Werteübergabe / der
Returnwert. Und um sicherzustellen, dass es immer funktioniert, hab
ich halt Funktionen drumgebaut.
Z.B.:
@Markus: Bessere Vorschläge werden gerne angenommen! Nur bitte sachlich
bleiben...
Ansonsten hätte ich ja - wie du sicherlich sehen kannst - einfach nur
die Zeile mit __ASM(...) ins Headerfile packen müssen,was erheblich
weniger Arbeit ist.
Diese Funktionen liessen sich übrigends nicht (gcc) als static inline
compilieren.
VG,
/th.
Erwin Reuss schrieb:
> Außerdem hat sich ST mit fehlerhaften Bootloadern in> der neuen Generation selber ins Abseits katapultiert.
Beim Errata Sheet der LPC1700 frage ich mich allerdings, ob das wirklich
ernst gemeint ist, oder ob der Beta-Test grad erst beginnt. Da ist man
in der Branche und grad auch bei NXP ja andere Listen gewohnt.
Random ... schrieb:
> Hatte mit AAPCS (gcc macht die ganze Registerzuordnung selbst, daher> stehen in dem ASM kram ja auch variablen drin und keine Register) zu> tun, Problem war die Werteübergabe / der Returnwert. Und um> sicherzustellen, dass es immer funktioniert, hab ich halt> Funktionen drumgebaut.
Nur mal so zu meinem Verständnis (ich verwende GCC nicht sehr oft),
was ist denn hier das eigentliche Problem? Ist das mal wieder ein
ARM-GCC Bug?
Gruß
Marcus
http://www.doulos.com/arm/
Random ... schrieb:
> drin und keine Register) zu tun, Problem war die Werteübergabe / der> Returnwert.
Worin konkret? Das ist übliche GCC Praxis seit Jahren. Auch mit
Parametern.
Ein Problem ist jedenfalls
denn da muss wie schon erwähnt unbedingt "=&r" rein, damit er die
Register von addr/value nicht für result wiederverwendet. Tut er in der
bestehenden Version zufällig bis zur nächsten Compilerversion nicht,
aber als inline-Version kann das schon mal vorkommen. Das result=0
vorneweg nützt nicht, schadet nicht.
> Diese Funktionen liessen sich übrigends nicht (gcc) als static inline> compilieren.
Warum nicht? Auch das ist gängige Praxis.
Ebenso STREXB/H. Es führt nur dazu, dass der Aufrufer routinemässig eine
Erweiterung auf 32-Bit durchführen muss, weil er mit 16-Bit Werten in
Registern (ausser beim Store) nichts anfangen kann. Passend erweitert
werden sie von den LDREX*/STREX* Befehlen sowieso schon.
> denn da muss wie schon erwähnt unbedingt "=&r" rein, damit er die> Register von addr/value nicht für result wiederverwendet.
warum?
technisch ist doch gegen
r0 = r0 + r1
nichts einzuwenden...
Funktionieren tuts, der Test hat jeweils hingehauen (CodeSourcery,
Raisonance).
> Wo wir grad dabei sind: Weshalb eigentlich uint16_t statt uint32_t> als Return-Wert in ...
LDREX Halfword
:-)
Darum sind dererlei auch drei drin. Wenn du (int) möchtest, verwende
bitte auch die LDREX :-)
Random ... schrieb:
> technisch ist doch gegen> r0 = r0 + r1> nichts einzuwenden...
Normalerweise nicht. Nur gibt ein paar Befehle, bei denen bestimmte
Überlappungen von der Befehlsreferenz ausdrücklich verboten werden.
ADD gehört nicht dazu, STREX jedoch schon.
Random ... schrieb:
> LDREX Halfword>> Darum sind dererlei auch drei drin. Wenn du (int) möchtest, verwende> bitte auch die LDREX :-)
Jetzt wäre mal ein weiterer Blick in die Referenz fällig. Was macht
LDREXH r0,[r1]
denn genau:
r0[0..15] = memory
r0[16..31] = 0
Eine Funktion
uint32_t __LDREXH(uint16_t *addr)
argh ihr habt es geschafft, mich völlig zu verwirren confused
Richtig müsste es heissen:
uint16_t __LDREXH(uint16_t *addr)
LDREX Halfword bekommt einen 16bit pointer auf eine variable, und gibt
einen 16bit wert zurück.
Also warum willste da 32bit return haben?
Random ... schrieb:
> LDREX Halfword bekommt einen 16bit pointer auf eine variable, und gibt> einen 16bit wert zurück.
Wenn damit der Maschinenbefehl gemeint ist: NEIN.
LDREX Halfword bekommt einen 32-Bit Pointer auf eine 16-Bit Variable,
und gibt einen 32-Bit Wert zurück. Genau wie LDR Unsigned Halfword.
Schau mal in die Befehlsreferenz!
A. K. schrieb:
> LDREX Halfword bekommt einen 32-Bit Pointer auf eine 16-Bit Variable,> und gibt einen 32-Bit Wert zurück. Genau wie LDR Unsigned Halfword.
Ist zwar technisch nicht ganz verkehrt, aber der Prototyp einer Funktion
gibt ja letztlich auch die Intention des Entwicklers an. Und die besteht
hier nun mal darin, ein Halbwort zu laden.
Gruß
Marcus
http://www.doulos.com/arm/
Ok, was bleibt?
Es ist alles korrekt, trotz des fehlenden =&r funktioniert es
(schliesslich ist der Kram nicht ungetestet rausgegangen, dazu gehört
noch ein Verifikationsprogramm, in welchem die CMSIS zerlegt wird).
Offen ist noch der Punkt, ob der gcc mittlerweile __ASM(...) als
__INLINE unterstützt, denn das war bisher nicht der Fall.
Daher existiert der Kram in der nervigen .c datei, die wir selbst auch
gerne loswerden wollen.
VG,
/th.
Random ... schrieb:
> Offen ist noch der Punkt, ob der gcc mittlerweile __ASM(...) als> __INLINE unterstützt, ...
Nein. Aber __asm und __inline unterstützt er schon seit mehr als
10 Jahren. (C ist case sensitive.)
Random ... schrieb:
> Ok, was bleibt?>> Es ist alles korrekt, trotz des fehlenden =&r funktioniert es> (schliesslich ist der Kram nicht ungetestet rausgegangen, dazu gehört> noch ein Verifikationsprogramm, in welchem die CMSIS zerlegt wird).
Das hängt hochgradig von der Registerallokationsstrategie an. Was in
4.3.2 funktionierte kann in 4.3.3 in die Hose gehen. So geschehen:
http://www.st.com/mcu/forums-cat-9006-23.html
arm-hitex-elf-gcc.exe -c -gdwarf-2 -MD -O0 -trigraphs -mcpu=cortex-m3
-mthumb -Wall -fsigned-char -mlittle-endian -mfpu=vfp -xc
-mno-thumb-interwork -mno-tpcs-frame -I.\Source\ -o .\objects\core_cm3.o
.\Source\core_cm3.c
/cygdrive/c/DOKUME~1/cad/LOKALE~1/Temp/ccXXSLdu.s: Assembler messages:
/cygdrive/c/DOKUME~1/cad/LOKALE~1/Temp/ccXXSLdu.s:694: Error: selected
processor does not support `strex r3,r3,[r2]'
> Offen ist noch der Punkt, ob der gcc mittlerweile __ASM(...) als> __INLINE unterstützt, denn das war bisher nicht der Fall.
GCC tut das schon seit sehr langer langer Zeit. Wobei die Dinger (__ASM,
__INLINE) natürlich anders heissen.
@random
>> Gerade Luminary hat...>> haben die inzwischen ihre Core-Locks in den Griff bekommen?
Hat du eine Quelle oder kannst das näher beschreiben ?
Danke.
Random ... schrieb:
>> Schau mal in die Befehlsreferenz!> Lt. Quick Reference Card gibt der LDREXH die Bits [15..0] zurück.
Die Refcard interessiert mich in diesem Zusammenhang nicht, die ist
keine komplette Befehlsbeschreibung. Die ARMv7 Referenz schon eher.
> Die Refcard interessiert mich in diesem Zusammenhang nicht, die ist> keine komplette Befehlsbeschreibung.
Willste damit sagen, dass die falsch ist?
Auch im Netz steht es so - in der kompletten Referenz...
Sooo, gerade mal getestet mit latest code sourcery.
Entgegen meinen obigen Ausführungen lag damals das Problem nicht bei asm
und inline, sondern dem ganzen in Verbindung mit static, was bei
funktionen im headerfile ja notwendig ist.
Dies hier ist nun compilierbar:
Random ... schrieb:
> Auch im Netz steht es so - in der kompletten Referenz...
Aus der ARMv7 Referenz:
"LDREXH
Load Register Exclusive Halfword derives an address from a base register
value, loads a halfword from memory, zero-extends it to form a 32-bit
word, writes it to a register ..."
Random ... schrieb:
> Dies hier ist compilierbar (ungetestet):
Aber Unsinn.
Was hast du gegen die Inline-Funktion? Präprozessor-Makros sind bei GCC
vollkommen unnötig, die "static __inline" Variante ist das Optimum.
sooo .....
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0098a/armccref_cjaeccjj.htm
Where:
ptr
points to the address of the data to be loaded from memory. To
specify the type of the data to be loaded, cast the parameter to an
appropriate pointer type.
Ich denke, damit ist die CMSIS richtig :-)
Geladen wird B/H/W in ein W Register (alles bei ARM ist 32Bit. Danach
muss man das interpretieren wie gewünscht.
Da ich 16 Bit erwarte, wenn ich 16Bit lade, passt das.
> Was hast du gegen die Inline-Funktion? Präprozessor-Makros sind bei GCC> vollkommen unnötig, die "static __inline" Variante ist das Optimum.
Ich habe nix dagegen. Sie sind sauber, übersichtlich, schnell.
Das static ist hier notwendig gegen includes in verschiedenen Modulen.
Es geht nur darum, Marcus' Vorwurf der Faulheit auszuhebeln ^^
Der gcc Kram für die CMSIS war bei weitem der grösste Batzen Arbeit des
CMSIS CM3 Core :-) Und natürlich kann man nur das umsetzen, was derzeit
vom jeweiligen Compiler unterstützt wird. Und da kam nun mal bei asm ein
"not allowed" vom Compiler ^^
Da das jetzt aber scheinbar funktioniert, werden wir das umsetzten,
testen und mit der nächsten Version rausgeben.
Btw: Ich würde mir deine Version gerne mal ansehen :-)
VG,
/th
Random ... schrieb:
> Es ist alles korrekt, trotz des fehlenden =&r funktioniert es
"Absence of evidence is no evidence of absence."
So, wie ich eure Diskussion verstanden habe, ist das =&r sehr wohl
notwendig. Dass es bei dir erst einmal funktioniert, ist purer
Zufall. Um den derart funktionierenden Code in nicht (mehr)
funktionierenden umzuwandeln bedarf es dann noch nicht einmal eines
Compilerupgrades (neue Version belegt gerne mal die Register anders),
sondern es genügt bei der inline-Variante dann ganz simpel, dass
sich das Drumrum der aufgerufenen inline-Funktion ändert, schon
knallt's.
Solange deine Bibliotheksfunktion in einem separaten C-File compiliert
worden ist, war das was anderes: sobald das mit einer Compilerversion
funktioniert, hängt das Compilat dann nicht mehr vom restlichen
Sourcecode des Anwenders ab, da es ja erst vom Linker eingebunden wird.
Eine Erklärung für die Wirkung des &-Modifiers (wenn auch für den
AVR, aber sollte für deine ARM-Problematik nachvollziehbar sein) findest
du auch hier:
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html#io_ops
Jörg Wunsch schrieb:
> Solange deine Bibliotheksfunktion in einem separaten C-File compiliert> worden ist, war das was anderes:
Sogar in der separat übersetzten Version hat es bereits mal geknallt,
wie der oben erwähnte Link ins STM32-Forum zeigt.
Random ... schrieb:
> Btw: Ich würde mir deine Version gerne mal ansehen :-)
Bittesehr. Ich hatte CMSIS 1.20 aus der STM32 Lib 3.1.2 als Basis
verwendet und da ist __asm bereits enthalten - aber natürlich nicht die
dazu passenden Funktionen.
Ich hatte für mich den ganzen non-GCC Kram rausgeworfen um den
Überblick zu behalten. Tip: deutliche Trennlinien zwischen den Varianten
der verschiedenen Compiler kosten den Compiler nichts, machen den Code
aber lesbarer.
Ich nehme an, die "naked" Verzierungen der PSP/MSP-Funktionen haben
einen tieferen Sinn, der sich mir nur noch nicht erschlossen hat. Die
kann man natürlich nicht exakt so wie im Original inlinen ;-).
Ist ja nett dass ihr meinen Thread vom STM Forum bereits hier
diskutiert.
(Hallo prx - beste Grüße aus Stuttgart)
>http://www.st.com/mcu/forums-cat-9006-23.html>arm-hitex-elf-gcc.exe -c -gdwarf-2 -MD -O0 -trigraphs -mcpu=cortex-m3>-mthumb -Wall -fsigned-char -mlittle-endian -mfpu=vfp -xc>-mno-thumb-interwork -mno-tpcs-frame -I.\Source\ -o .\objects\core_cm3.o>.\Source\core_cm3.c
schliesslich muß nicht jeder selber drüberstolpern. Der -mfpu=vfp switch
ist für den CM3 übrigens hochgradiger Schwachsinn da keine HW Floatpoint
und nur deshalb drinnen, weil die Hitex Template den drinnen hatte.
Sobald die C- Laufzeit Lib verwendet werden soll krachts. Darüber hinaus
hat der Startup Code aus der periph_lib V3.1.2 noch mehrere weitere
heftige Fehler worüber ich obigen Thread bereits akutalisiert habe.
Jedenfalls scheint es von NXP diesbezüglich gar nichts zu geben (?)
während STM wenigstens noch was fehlerhaftes liefert.
Nun aber der Hammer: Übersetzt man die V3.1.2 mit einem GCC von
Codesourcery, z.Bsp. mit der Oberfläche von Raisonance, so kriegt man
gar nichts mit und alles scheint in bester Ordnung zu sein. Eine
Nachfrage beim Raisonance Support hat ergeben, daß die Entwickler dort
über die Fehler von STM wissen, diese bei STM bereits reklamiert haben
und selbst eine korrigiert Version in ihrer Lib eingebaut haben. Daher
kriegt man als normaler Anwender nix mit. Erst beim F107 mussten die
einen externen Startup drüber setzen, in der Periph_lib V3.1.2 ist aber
nur der low density startup Schrott.
Falls jemand weis, warum STM in ihren Beispielen die eigenen Header
doppelt neu definiert, bitte melden (Bsp. siehe im STM Forum Thread
"Multiple channel ADC"
Aber genug - ich mach mal weiter oben einen neuen Thread zu Hitex auf.
So langsam krieg ich mit dem Teil nämlich graue Haare und wünsche mir,
dass die Werbeleute meinem Kunden beibringen warum es nur bei mir ein
viertel Jahr dauert bis man durchblickt und irgendwas geht ...
@A.K.:
Vielen Dank. Im Grunde hast du ja nur die Funktionen aus der .c in die
.h kopiert und mit static inline verziert. Das funzte damals halt nicht
(irgendwas mit inline assembly not allowed in wasAuchImmer, ist ne
Weile her.
Wir werden die CMSIS dahingehend überarbeiten.
Btw: Auch bei dir ist kein =&r drin ^^
---
Mal ne generelle Frage zum gcc, da ich - wenn ASM - fast nur mit dem
armcc unterwegs bin:
Hält sich der gcc-arm an die AAPCS (also r0..r3 = parameter, r0 =
return) ?
Ich bin nämlich bei meiner recherche damals darüber gestolpert, dass dem
nicht zwingend so ist ...
VG,
/th.
Hallo Thorsten - falls du zu den Machern von CMSIS gehörst (bei Keil ?)
Das strex Problem interessiert mich momentan nicht, aber es wäre nett,
wenn du noch dazu was sagen könntest:
1) in den startup.s fehlende .thumb_func zum setzen des T-Bits
2) Header Hierarchie in Bezug auf das assert_param Makro
3) wiederholte Define von absoluten Registeradressen in main.c
Beispielen
Ich habe das nur dort reingeschrieben wo es erforderlich ist.
> Hält sich der gcc-arm an die AAPCS (also r0..r3 = parameter, r0 => return) ?
So weit ich weiss ja.
> Ich bin nämlich bei meiner recherche damals darüber gestolpert, dass dem> nicht zwingend so ist ...
Details?
>> Ich bin nämlich bei meiner recherche damals darüber gestolpert, dass dem>> nicht zwingend so ist ...>>Details?
Muss ich passen, weiss ich nimmer :-)
Das ist aber der Grund, warum ich das so kompliziert gemacht hab,
anstatt die Parameter einfach in die Register zu laden (siehe armcc).
z.B. hier, da ist nix drin von wegen parameter und return, da ich vom
AAPCS ausgehen kann:
A. K. schrieb:
> Ich habe das nur dort reingeschrieben wo es erforderlich ist.
PS: Und wo ich von janvi drauf gestossen wurde ;-). LDREX könnte wohl
auch welche brauchen ;-)
Random ... schrieb:
> Hält sich der gcc-arm an die AAPCS (also r0..r3 = parameter, r0 => return) ?
Ja. Auf jeden Fall länger als es CMSIS gibt.
Gruß
Marcus
http://www.doulos.com/arm/