www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ARM-Beginn


Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Nach einiger Zeit & Arbeit mit AVRs und ausgiebiger Theorie in anden
8Bit Mikrocontrollern wollte ich mich mal mit dem ARM-µC
ausseinandersetzen (praktisch, nicht theoretisch). Nun stehe ich aber
vor dem Problem, dass ich weder weiß, woher ich nun einen ARM bekomme
noch wie ich tqfp löten soll. Ein Development Board oder ähnliches will
ich mir nicht kaufen weil sie a) zu teuer sind und b) nicht sehr
"flexibel" sind.

Ich hab mich mal bei Segor umgeguckt und dort die LPCs von Philips
entdeckt. Kann man die "gebrauchen" (jetzt bitte nicht nach der
Anwendung fragen, mir gehts um die so genannte
"Benutzerfreundlichkeit", denn wenn es um 16/32Bit Controller geht,
ist das für mich Neuland)?

Ich traue mich auch nicht daran mir nun einen teuren µC zu kaufen um
ihn nachher beim löten zu zerstören. Ich habe bei Segor aber leider
keinen Sockel gefunden und die meisten die man so im Internet entdeckt
sind soooo teuer, dass man gleich auf das Development Board
zurückgreifen kann.

Was könnt ihr mir empfehlen? Wo kann man die ARMs am besten kaufen
(nicht umbedingt LPC), wer stellt die her, und wie bring ich die auf
mein Board (erleichtert die Multiadapterplatine von Reichelt die Sache
wegen dem Lötstopp)?

Danke!!!

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Olimex-Evaluation-Board mit LPC2106, das im hiesigen Shop für 70 €
verkauft wird, hast Du bereits entdeckt?

Passende Lötadapter zum Gehäuse des LPC2106 gibt es bei
www.elk-tronic.de - zum wirklich unschlagbar günstigen Preis.
http://www.elk-tronic.de/Products/Adapter/SolderAd...

Prinzipiell ist der 2106 ein sehr netter Controller. Mit 64 KByte RAM
und 128 KByte Flash ziemlich "fett" ausgestattet, sind nur die
I/O-Leitungen etwas schwach bestückt, vor allem, wenn man über das
JTAG-Interface debuggen will. Dann nämlich fällt die Hälfte aller
I/O-Pins flach.
Geschwindigkeit und elektrische Leistungsaufnahme des 2106 sind
annähernd ziemlich beeindruckend - "mächtig gewaltig", wie ein
Filmdarsteller zu sagen pflegte.
(60 MHz Takt, annähernd entsprechend 60 MIPS auf einer echten
32-Bit-Maschine, und das bei ca. 60 mW Leistungsaufnahme)

Extrem bastelgeeignet ist der 2106 dadurch, daß seine I/O-Anschlüsse
5V-kompatibel sind. Obwohl das Teil selbst nur mit 3.3V (und 1.8V)
betrieben wird, kann und darf man 5V-Peripherie dranhängen. Das
vereinfacht vieles.

Im Gegensatz zur Harvard-Architektur der AVR-Prozessoren ist der ARM
eine von-Neumann-Maschine, was bedeutet, daß RAM und ROM im gleichen
Adressraum liegen. Das dürfte viele Stolpersteine der C-Programmierung
beseitigen; viele Probleme, die hier im Zusammenhang mit AVRs und
C-Programmierung gepostet werden, sind darauf zurückzuführen.

Sehr ratsam ist die Anschaffung (und Benutzung) eines JTAG-Interfaces.
Das einfachste ist ein Parallelportadapter namens "Wiggler", ein
Nachbau davon wird hier im Shop für 20€ verkauft. Geeignete Software
vorausgesetzt, wird der JTAG-Adapter sowohl für die Programmierung als
auch für das Debuggen eingesetzt.
(Die LPC21xx-Prozessoren kann man auch über die serielle Schnittstelle
programmieren, dazu gibt's von Philips kostenlose Software. Aber eben
nur programmieren, nicht debuggen.)

Auf Windows-Maschinen habe ich bislang nur ein recht teures
Entwicklungssystem gesehen, mit dem der "Wiggler" akzeptabel
funktioniert - das ist Crossworks for ARM von Rowley. Die Debugsoftware
der Firma, die den Wiggler entwickelt hat (Macraigor), ist auf meinem
Rechner nicht verwendbar - das liegt vermutlich an der Kombination
Betriebssystem/Rechenperformance (XP auf pIII-500).

Leider ist genau diese Software erforderlich, um mit der Kombination
GCC-GDB (gnu debugger) arbeiten zu können.
Das mag mit anderen Umgebungsbedingunen alles anders aussehen
(schnellerer Rechner, dümmeres Windows (95-Me) oder Linux).

Auch das Entwicklungssystem von IAR setzt auf die Macraigor-Software,
ist also auf meinem System nicht verwendbar.

Das erfreuliche am ARM-Kern ist, daß nicht nur ein Hersteller ARMe
herstellt (wie es beim AVR der Fall ist), und daß es nahezu beliebige
Varianten davon gibt.
An welche davon man zu welchen Konditionen gelangt ... das weiß ich
allerdings nicht. Immerhin: Segor verkauft den 2106.

*) Links:
www.rowley.co.uk ("Crossworks for ARM" für Windows und Linux,
30-Tage-Demo download- und registrierbar. Vollversion kostet 500 UKP,
also knapp 800€)
www.macraigor.com ("OCD Commander" für Windows und Linux, frei)

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle und asführliche Antwort!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"...wenn man über das JTAG-Interface debuggen will. Dann nämlich fällt
die Hälfte aller I/O-Pins flach."

???

Seit wann braucht JTAG 16 Pins ?


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die 60 MIPS bei 60MHz sind aber wirklich nur der aller-alleräußerste
Spitzenwert.

Über 20MHz kommt nämlich der Flash nicht mehr voll mit und muß
jedesmal, wenn was nicht im Cache steht, zusätzliche 2 Zyklen
pausieren. D.h. man erreicht bei 60MHz im Schnitt nur etwa die doppelte
Geschwindigkeit, wie bei 20MHz.

Viele Befehle dauern auch 2 Zyklen.
Ein simples Pin setzen in C kostet 3 Befehle also insgesamt 6 Zyklen.

Ich hab mal testweise mit einem Timerinterrupt nur eine Variable
hochgezählt, sonst nichts. Da konnte ich die Interruptfrequenz auf
maximal 60 Zyklen setzen oder es gehen Interrupts verloren.

D.h. nur Interrupt betreten, Interruptflag löschen, Wert hochzählen und
Interrupt verlassen kostet allein schon mal etwa 50 Zyklen.


Peter

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist aber dürftig.
Mit 8051ern übertrifft man das locker.

Da sieht man mal wieder, dass Marketing alles ist...

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist aber bei den Silabs 100MIPS 8051-ern auch so.

Bis 25MHz schaffts der Flash, d.h. bis dahin sind alle Befehle
konstant.
Darüber kann es dann bei Sprüngen oder Tabellenzugriffen zu
zusätzlichen Wartezyklen kommen.

Ich hatte bisher nur die 25MHz-Typen getestet, hab also keine Ahnung,
wie gut der Flash-Cache bei 100MHz arbeitet.



Bei den LPC könnte man auch noch besonders eilige Funktionen, die viele
Sprünge beinhalten, in den SRAM auslagern, da der SRAM schneller ist.
Ich weiß aber nicht, wie man dazu den Keil konfigurieren muß.

Es ist auch nicht so leicht, für den ARM alle Informationen zusammen zu
stellen, ein Gesamtdatenblatt gibt es nämlich nicht.
Es ist alles auf eine Unmenge verschiedener Application-Notes verteilt,
in denen immer nur einzelne Bruchstücke stehen.
Zusammen dürften das vermutlich etwa 1000 Seiten oder mehr sein.


Richtig punkten kann der ARM wohl nur, wo viele 32 Bit Berechnungen
auf große Datenmengen auszuführen sind. Um eine Assemblerprogrammierung
wird man aber nicht umhinkommen, wenns richtig schnell sein soll.


Peter

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
Zwar stimmt es, daß das JTAG-Interface keine 16 I/O-Anschlüsse
benötigt, aber in der Beschreibung des Registers PINSEL1 (im Datenblatt
auf Seite 14 und im User Manual auf Seite 79) heisst es:
  "Function control for the pins P0.17 - P0.31 is effective only
  when the DBGSEL input is pulled low during RESET."

Um via JTAG programmieren und debuggen zu können, muss DBGSEL aber
während des RESET high sein.

Dies unschöne Einschränkung wird auch in der knappen Dokumentation des
Olimex-Entwicklungsboards beschrieben :

  "Note: to enable JTAG interface DBG jumper
  should be shorted at the time of POWER UP.
  Important: when JTAG is enabled P0.18-P1.31
  ports take their JTAG alternative function no
  matter of PINSEL register value, so during
  debugging with JTAG these ports are not
  available for the user program."

Das ist allerdings keine Einschränkung von ARM-Prozessoren generell,
sondern der LPC210x-Varianten von Philips.

Deine Ausführungen zur Geschwindigkeit lassen befürchten,
daß der Aufwand, den Philips für die Geschwindigkeitssteigerung von
Lesezugriffen auf das Flash-ROM betrieben hat, irgendwie im Leeren
verpufft.
Mit "Cache" meinst Du vermutlich das MAM; wenn ich mir die
Beschreibung im User Manual ansehe, klingt das doch erstmal alles ganz
toll ...
Wie waren bei Deinen Messungen MAMCR und MAMTIM programmiert?

(Zu eigenen Messungen bin ich leider aus zeitlichen Gründen noch nicht
gekommen)

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus,

wenn das wirklich so ist mit den 16 verlorenen JTAG-Pins, dann ist das
ja echt krank !

Muß ich mal ausprobieren.


Ein Kollege von mir hat auch einige Merkwürdigkeiten entdeckt:

1.
Für das Master SPI muß der SS-Pin mit auf SPI definiert werden, obwohl
man ihn nicht braucht, sonst funktioniert das ganze SPI nicht.

2.
Für die UART muß RXD und TXD belegt werden, auch wenn man nur eins
davon braucht.

Diese Pinverschwendung ist beim besten Willen nicht einzusehen !

Auch weiß ich keinen Grund, warum umdefinierte Pins nicht ständig mit
dem Eingangsregister verbunden bleiben können, d.h. immer wenigstens
als Eingang nutzbar währen.


Das MAM habe ich optimal konfiguriert.
Allerdings ist meine kleine Testroutine mit häufigen Interrupts dafür
wohl der worst case.
Es wird warscheinlich bei größerem Code, wo mehr Code hintereinander
steht, günstiger sein.


Peter

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jan,
es gibt auch von Atmel Arm7 Controller (AT91) und auch
Entwicklungsumgebungen mit passender Software. Zum Einstieg bietet sich
da das AT91EB40 an. Ich konnte meines bei Ebay für lächerliche 29€
ersteigern (zwar in der alten Verison aber zum Einstieg reicht das
völlig).

Autor: Matthias Friedrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"1.
Für das Master SPI muß der SS-Pin mit auf SPI definiert werden, obwohl
man ihn nicht braucht, sonst funktioniert das ganze SPI nicht."

Das ist richtig und ein Bug, der in den neueren lpc-Varianten mit der
neuen SPI-Unit behoben ist (2130...).

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, häufige Interrupts dürften das Funktionskonzept des/der MAM effektiv
durchstreichen. Ist halt kein echter Cache-Controller.

Für ein erstes Hineinschnuppern in die ARM-Gefilde ist die
LPC210x-Reihe  trotz der erwiesenen Einschränkungen dennoch geeignet.

Andere ARMe sind natürlich deutlich interessanter. Kennt wer 'ne
Bezugsquelle für die OKI 67400-Serie? Der ML67Q4003 würde mich
besonders interessieren.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Atmel bietet ein Entwicklungsboard mit den neuen SAM7S (ARM7TDMI) inkl.
JTAG-Debugger (USB-Anschluss) Hardware und IAR-Compiler (32kB
limitiert) fuer ca. 300 Euro inkl. Steuer. Auf dem Atmel-ARM ist sogar
ein USB-slave-Modul und zumindest lt. Papier sind einige Limitierungen
wie man sie im LPC210x findet nicht vorhanden. Mehr dazu auf
www.at91.com. Wie schon angemerkt, sind die neuen LPC213x ueberarbeitet
und haben weniger "Macken" - zumindest auf dem Papier. Das Atmel-Kit
war vor ein paar Wochen bei Ineltek lieferbar, keine Ahnung ob immer
noch dort auf Lager. Ich hab das noch nicht selbst, aber der Preis ist
fuer das gebotene sehr gut. Der USB->ARM/JTAG-Adapter kostet "normal"
alleine schon soviel. Nichts desto trotz ist das Olimex LPC-P2106 bzw.
LPC-P1 ganz brauchtbar fuer eigene Experimente, JTAG debugging/ICE ist
zwar praktische aber nicht unbedingt erforderlich.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für den Hinweis auf die AT91SAM7S-Reihe. Das scheint ja ein
ziemlich direkter Konkurrent der LPC210x-Reihe zu sein; ist bekannt,
was in etwa die Teile kosten?
(Beispielsweise der SAM7S256)

Das erwähnte Angebot ist bereits wegen des USB-JTAG-Interfaces ziemlich
interessant.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal unter http://groups.yahoo.com/group/lpc2000/messages/ schauen.

Die ARM7 sind nicht mit 8051 vergleichbar. Spielen in einer anderen
Liga.

Autor: Mathias Friedrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon, aber die kleinen ARMs sind die 8051 und AVR der Zukunft, vor
allem wenn man sich den Preis anschaut.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Die ARM7 sind nicht mit 8051 vergleichbar. Spielen in einer anderen
Liga."

Interessant sind die LPC schon geworden, da sie nun nicht mehr teure
Multilayer mit externem RAM und Flash benötigen und auch lötbar sind
(kein BGA).

"Andere Liga" stimmt also nicht mehr.


Aber nur beim Rechnen 32 Bit und großen Datenmengen kann der ARM
punkten.
Bei logischen Operationen wie Bitschubsen (Portpins) oder Statemachines
zieht er den kürzeren gegenüber dem 8051.


Peter

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorweg: ich bin kein ARM-Experte und hab nur etwas mit dem LPC-P2106/P1
Board rumgespielt und ziemlich viel im inet gelesen. Es ist so, dass zu
dem eigentlichen "Prozessorkern" auf dem Chip weitere Module (GPIO,
UART, SPI, PWM etc.) ueber einen oder mehrere Bus(se) angebunden
werden. Dieser Bus ist nicht "beliebig" schnell und das ist der
Hauptgrund warum "bitbangen" (bzw. "-schubsen") auf "dem ARM"
nicht sonderlich schnell ist (lt. Philips/yahoo-gruppe sind auf dem
LPC2106 bei ca. 60MHz Systemtakt ungefaehr 3,5 MHz "Bitbangfrequenz"
moeglich). Ein mit 16MHz getackteter AVR schafft im Prinzip auch 16MHz,
so richtig verstanden - ich hab' solche Geschwindigkeiten bisher nie
gebraucht. Diese Begrenzung scheint sowohl in der ARM7DTMI-S-Serie von
Philips (LPC2xxx), also auch in der ARM7DTMI-"SOC"-Serie von Atmel
(AT91SAM7S/A) vorhanden (und wohl auch bei den Teilen von Analog und
ST). "Zukuenftige" Controller, die vielleicht das GPIO-Modul
anders/schneller an den Prozessorkern anbinden, sind moeglicherweise
deutlich schneller im "Portpins wackeln lassen".

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Endlich bin ich mal dazu gekommen, mir den LPC2106 mal etwas näher
anzusehen.

Peters Aussage
> Ein simples Pin setzen in C kostet 3 Befehle also insgesamt 6
Zyklen.

sieht disassembliert so aus:

Ein harmloses Statement wie

      IOCLR = 0x00000080;

sieht disassembliert so aus:

0x0000058C 0xE3A032CE  mov r3, #0xE000000C
0x00000590 0xE283390A  add r3, r3, #0x00028000
0x00000594 0xE3A02080  mov r2, #0x00000080
0x00000598 0xE5832000  str r2, [r3]

Zunächst rieb ich mir verwundert die Augen; was zum Teufel hat die
Addition da verloren?
Bei Betrachtung der Adressen und der Operandengröße wurde mir dann aber
einiges klar. Jede der vier Instruktionen ist exakt 32 Bit lang - das
sind die Operanden aber auch.
Also werden die 32-Bit-Operanden "gepackt", um mit in den
32-Bit-Opcode untergebracht zu werden.
Der Wert 0xE002800C (das ist das Register IOCLR) lässt sich nicht in
einen Opcode packen und muss daher durch eine Addition der in eine
Instruktion packbaren Werte 0xE000000C und 0x28000 gebildet werden.
Anscheinend gibt es auch keine Möglichkeit, eine Konstante in eine in
einem Prozessorregister enthaltene Adresse zu schreiben, daher muss
erst die Konstante in ein Register geladen werden (was hier wohl
glücklicherweise in einem Rutsch geht) und dies dann indirekt über das
andere Register in den Speicher geschrieben werden.

Ich hab' mir mal den Spaß gemacht, und mir die Funktion der
Instruktion 0xE283390A im ARM7-TDMI Manual näher anzusehen.
Das ist die Addition der Konstanten 0x28000 zum Register R3 - der Wert
wird durch eine 32-Bit-Rotation des 8-Bit-Wertes 0x0A gewonnen (9*2 mal
nach rechts). Diese Operation wird in einem* Takt ausgeführt.
Geht's noch komplizierter?

Damit hatte ich nicht gerechnet, aber es erscheint nach einiger
Überlegung logisch. Nur durch so eine Vorgehensweise kann die
Instruktionslänge auf 1 DWORD und so auch die Ausführungszeit auf 1
Takt pro Instruktion** beschränkt bleiben.

Nun, das wird wohl der RISC/CISC-Unterschied sein.
Das ist natürlich ziemliche Grütze, weil so die Ausführungszeit
folgender C-Zeilen unterschiedlich ist:

  unsigned long Variable;

  Variable = 0xE000000C;  // schnell

  Variable = 0xE002800C;  // langsamer

Damit hatte ich nun wirklich nicht gerechnet.

Trotzdem: Noch gefällt mir der ARM, da er dennoch das Potential hat,
diese Nachteile durch hohe Taktfrequenz und leistungsfähige, wenn auch
verkorkste Operationen wettmachen kann.
Die oben erwähnte Addition ist immerhin exakt gleichschnell, auch wenn
statt
  0xE283390A  add r3, r3, #0x00028000

  0xE283290A  add r3, r2, #0x00028000
da steht, das Ergebnis der Addition also in r2 landet.
Register = Register + Konstante in einem Takt (wenn denn die Konstante
mitspielt ...)

Was das Bitbanging betrifft, so müsste mit einem Assemblerkonstrukt à
la

Bestimme Adresse IOSET, Ergebnis in Register1
Bestimme Adresse IOCLR, Ergebnis in Register2
Konstante 0x80 in Register3

Schleife:
  str Register2, [Register1]
  str Register2, [Register2]
  wiederhole Schleife

die maximale Ausführungsgeschwindigkeit des Codes möglich sein.
str benötigt zwei Zyklen, der Branch-Befehl benötigt drei Zyklen.

Ein Schleifendurchlauf erfordert also 7 Zyklen, kann aber auf dem 2106
mit 60Mhz Takt durchgeführt werden, da die MAM vier (oder gar acht)
komplette Instruktionen in einer Art "Cache" vorhält, hier also das
Flash-Rom nicht bremsend in Erscheinung tritt.
Das setzt allerdings voraus, daß der Peripherietakt gleich dem
Prozessortakt ist, was aber laut Programmierhandbuch möglich ist (VBP
Divider = 01).
Daraus resultiert der sehr akademische Grenzfall von 7 Takten
Ausführungsdauer, was bei 60 Mhz Takt in etwa 8.5 Mhz
"Wackelfrequenz" resultiert.
Wenn ich das richtig verstehe, liegt hier die Einschränkung nicht in
der Anbindung der Peripherie an den Prozessorkern, sondern mehr in der
Komplexität des ARM-Befehlssatzes.

Vergleiche ich den synthetischen Wackler mal mit dem Befehlstiming des
AVR, dann sieht das in der Tat etwas günstiger für den AVR aus.

Registerinhalt an Port ausgeben (OUT) benötigt einen Takt,
Branch (RJMP) benötigt zwei Takte.

Die obige Schleife würde also in vier Takten durchlaufen.

Damit ist der AVR bei diesem synthetischen Vergleich doppelt so schnell
wie ein ARM7TDMI.

Tja. Bei einer 32-Bit-Multiplikation (die natürlich wertabhängig
unterschiedlich lange dauert) ist der ARM mit drei bis sechs*** Takten
aber dem AVR etwas überlegen.


*) der LPC2106 hat ein 32 bit breites Speicherinterface, benötigt also
nicht wie andere kleine ARM-Varianten zwei 16-Bit-Speicherzugriffe für
eine Instruktion.
**) jedenfalls bei den hier zitierten.
***) ich will nicht ausschließen, daß ich die "Instruction Cycle
Timings" völlig fehlinterpretiere. Es ist schon spät.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Betr. der Geschwindigkeitsbegrenzung zum Pinwackeln gibt es ein etwas
laengere Stellungnahme von "philips_apps" (ein Philips-Angestellter)
in der lpc2100 yahoo-group. Ein einem Forum auf at91.com gibt es eine
vergleichbaren Betrag von einem Atmel-Mitarbeiter mit ähnlichem Inhalt.

http://www.at91.com/www/phpBB2/viewtopic.php4?t=333
Betr. der JTAG-"Pinverschwendung" beim LPC21xx. Nutzt man den
"secondary JTAG"-Anschluss, kann man wohl einige Pins wieder fuer
GPIO freigeben. Es gibt dazu eine App-Note und ein paar Beitraege in
der LPC2100-yahoo-Gruppe. (Nie selbst ausprobiert).

Martin

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das mit dem "secondary JTAG" hab' ich auch schon im Datenblatt
entdeckt. Die Frage ist nur, wie man das verwendet und ob das mit den
üblichen Debuggern zusammen überhaupt funktioniert.
Ich verwende derzeit zum Testen Crossworks von Rowley (weil damit der
Olimex-Wiggler anständig funktioniert), und natürlich erwähnt dessen
Dokumentation nichts davon.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus,

0x0000058C 0xE3A032CE  mov r3, #0xE000000C
0x00000590 0xE283390A  add r3, r3, #0x00028000
0x00000594 0xE3A02080  mov r2, #0x00000080
0x00000598 0xE5832000  str r2, [r3]


Also der Keil macht daraus:

   19:   IOCLR = 0x00000080;
 0000001C  E3A01080  MOV         R1,#0x80
 00000020  E5100000  LDR         R0,=0xE002800C
 00000024  E5801000  STR         R1,[R0,#0x0]

Von der Laufzeit dürfte das keinen Unterschied machen.
Nur der Code wird kleiner, wenn der Wert 0xE002800C mehrmals benötigt
wird.

Beachten muß man auch, daß der IO-Takt auf volle Pulle gesetzt wird,
sonst kommen noch zusätzliche Wartezyklen hinzu.


Peter

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:

Dein Assemblerlisting macht mich stutzig.

 0000001C  E3A01080  MOV         R1,#0x80
 00000020  E5100000  LDR         R0,=0xE002800C
 00000024  E5801000  STR         R1,[R0,#0x0]

Hier ist jede Instruktion -wie bei mir auch- 32 Bit groß und verwendet
offensichtlich keine zusätzlichen Operanden (was man an den Adressen
sehen kann).

Wie kann dann aber
  LDR R0,=0xE002800C
(Lade Register mit 32-Bit-Konstante)
mit einem 32-Bit-Code übersetzt werden? Wo im Speicher steht denn die
Konstante 0xE002800C?

Betrachte ich mir Seite 4-28 im "ARM Instruction Set Manual", dann
wird das ganze völlig unklar. Anscheinend bedeutet der Opcode E5100000
etwas vollkommen anderes.

Den Opcode kann man in einzelne Nibbles zerpflücken, um Tabelle 4-14
anwenden zu können:

E         - Cond (Bedingung- hier: Immer)
 5        - 0101 I = 0, P = 1:
                     Immediate Offset
                     Pre-indexing
  1       - 0001 UBW = 0, L = 1:
                     Offset abziehen
                     Word Transfer
                     kein Write-Back
                     aus Speicher laden
   0      - 0000 Base Register R0
    0     - 0000 Destination Register R0
     000  -      Immediate Offset, hier 0


Was auch immer diese Instruktion anstellen mag, die Konstante lädt sie
nicht ins Register. Da muss vorher (vor den drei angegebenen
Instruktionen) schon irgendwas mit geschehen sein.

Interessant ist der Vergleich dennoch - beide, Rowley und Keil
verwenden gcc als Compiler und produzieren anscheinend
unterschiedlichen Code.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Andere Liga" bei ARM bezieht sich auf Hochsprachen-Programmierung.
Bei kleinen Programmen für Microcontroller dominiert meist die I/O. Da
sind ARMs ineffizient. Jenseits der Grössenordnung von ca 10-30KB
bearbeitet der grösste Teil des Codes nur noch Daten- und
Kontrollstrukturen und setzt auf einigen wenigen I/O-Modulen auf. Dafür
sind 16/32-bit Architekturen wie ARM (aber auch MSP430) i.d.R. besser
geeignet als z.B. AVR. Auch nervt die AVR-sche Harvard-Architektur
bald, weil man stets zwischen den Pointer-Typen und Zugriffsmechanismen
unterscheiden muss.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus: Die Konstanten werden PC-relativ addressiert geladen und stehen
also irgendwo mittendrin im Code, im Umkreis von +/-4KB um den Befehl
herum. Beispielsweise hinter dem nächsten unconditonal branch. Der
Compiler sammelt derartige Konstanten erst einmal in einem Pool ein und
wann immer die Gelegenheit sich ergibt kommt ein Block derartiger
Konstanten.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@A.K.: Danke für den Hinweis. Das erklärt's ein bisschen. Interessant
ist allerdings, warum zwei gcc-Varianten unterschiedlichen Code zu
erzeugen scheinen, aber ohne ausführlichen Versions- und
Optionsvergleich wird man dem nicht weiter auf die Spur kommen können.

Von der Ausführungszeit her scheint allerdings die Variante der
Addition ("mein" Beispiel) sogar schneller zu sein; wenn ich die
Instruction Cyle Timings richtig verstehe, benötigt LDR drei Takte.
Auch hier will ich nicht ausschließen, daß ich mich da vertue; die
ARM-Dokumentation ist recht "akademisch".

Autor: Fritz Ganter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab heute auch ein bisserl mit dem ARM angefangen (ich hab ja gar
keine Ahnung von dem neumodischen Zeugs).

IO ist wirklich saulangsam, allerdings konnte ich den Teiler für den
Peripheriebus nicht auf 1 setzen, es lief dann nimmer. Geht nur mind.
2.

Ich hab dann einen kleinen 32-bit Integer-Rechentest gemacht:
  a = 2341;
  b = 3241;
  c = 17;

  for (i = 0; i < count; i++)
  {
    // IOSET = LED1_BIT;
    a = a * b / c;
    // IOCLR = LED1_BIT;
  }

Raus kommt dabei:
Atmel:

Rechentest mit 1000000 Durchläufen...
Ergebnis: 41956652
Dauer: 44.27 Sekunden, 44.270 µs

ARM:
Rechentest mit 1000000 Durchläufen...
Ergebnis: 41956652
Dauer: 3.80 Sekunden, 3.795 µs

Faktor: 11.6

Nur Multiplikation: Faktor 20.2 (also a = a * b).

Compiler:
ARM gcc 3.4.3, AVR 3.4.1, beide mit -O2 übersetzt.

Da ich bei meiner Arbeit eh Probleme mit Rechenzeit und ev. RAM
bekomme, überlege ich ob ich den süssen ARM als Rechenknecht dazupacke.
Ist wahrscheinlich sogar insgesamt kleiner (Mega32+ARM) als
ATmega64+RAM+Latch+viele bunte Leitungen.

Aber dann diese Umdenkerei: einmal 8 und einmal 32 bit.

Aber solange ich nicht in das Controllerprogramm  gtk_dialog_new ();
reinschreib, bin ich noch gesund. :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.