Forum: Mikrocontroller und Digitale Elektronik zwei Versionen Eine geht, die andere nicht AT91SAM7S256


von peter pippinger (Gast)


Lesenswert?

Hallo NG,

habe hier ein Problem. Einen Programmteil habe ich geschrieben. Der 
funktionier auch. Das selbe Assemblerkonstrukt eines compilierten C-Code 
funktioniert nicht. Aber warum? Dabei soll mal ausser acht gelassen 
werden, ob bei einer Routine solange gewartet wird, bis der Pin auf High 
/ Low ist, und bei dem anderen vielleicht umgekehrt. Es sollte auf jeden 
Fall in beiden Versionen einen Zustand geben, in dem gewartet wird, bis 
sich der Zustand ändert.

1. Meine Version (geht):
card_present:
  LDR  r0, =PIO_BASE
  LDR  r1, [r0, #PIO_PDSR]
  AND   r1, r1, #BIT15
  CMP  r1, #BIT15
  BNE  card_present

2. Die Version aus dem C-Konstrukt vom Compiler (geht nicht)
card_present:
  LDR  r1, =PIO_BASE
  LDR  r1, [r1, #PIO_PDSR]
  LSL  r1, r1, #16
  BMI  card_present

von peter pippinger (Gast)


Lesenswert?

Muss ich vielleicht irgend etwas beachten, um den BMI verwenden zu 
können? Hab echt keine Ahnung, warum das nicht funktioniert... LSL wäre 
doch der Befehl, der in Bsp2 den BMI beeinflusst, oder?

von peter pippinger (Gast)


Lesenswert?

Also so wie ich das sehe, schiebt die Compiler-Version das zu prüfende 
Bit an bit31. Das sollte doch eigentlich das Bit für positiv- / negativ 
Zahlen sein, oder? Wieso zieht aber dann BMI nicht?

von peter pippinger (Gast)


Lesenswert?

Habe jetzt mal zum Testen folgendes gemacht:

card_present:
  LDR  r1, =11111111111111111111111111111111b
  LSL  r1, r1, #15
  BMI  card_present

Meines Erachtens nach sollte da doch eine Endlosschleife herauskommen. 
Tut es aber nicht. Warum nur? Bit31 sollte doch auf jeden Fall "1" sein 
und somit N im Statusregister gesetzt. Ist es aber nicht.

Was mache ich da blos falsch?

von peter pippinger (Gast)


Lesenswert?

Verwendet den BMI denn niemand von euch?

von Andreas K. (a-k)


Lesenswert?

Doch. Aber ich setze vorher das Sign-Bit. Du nicht. Tip: Die CMP-Befehle 
sind die einzigen ALU-Befehle, die immer die Statusbits setzen. Bei den 
übrigen ALU-Befehlen muss man das extra sagen.

von peter pippinger (Gast)


Lesenswert?

@Andreas Kaiser
zunächst mal Danke für Deine Antwort. Allerdings verstehe ich es nicht. 
Was muss ich vorher sagen, und wie? Es sollte doch auch ohne CMP 
funktionieren, nachdem es ja scheinbar auch der Compiler so macht (siehe 
Beispiel 2).

Wäre echt nett, wenn Du noch einen konkreteren Satz darüber verlieren 
könntest...

MfG
Peter

von Andreas K. (a-k)


Lesenswert?

> Was muss ich vorher sagen, und wie?

Das war nun die falsche Antwort. Ich hatte noch eine gewisse Hoffnung, 
dass du doch mal das Handbuch absuchst, statt den einfachere Weg zu 
gehen und zu fragen.

Es funktioniert mit LSL (eigentlich: MOV r, r, r, lsl #...) sehr wohl, 
wenn man den Befehl auf die richtige Art angibt.

von Peter Pippinger (Gast)


Lesenswert?

Danke für Deine Hilfe.

Sorry, aber ich verstehe halt nicht, warum das so ist. Der Compiler 
erzeugt den Code aus Beispiel 2, nicht ich. Deshalb verstehe ich nicht, 
wie das überhaupt funktionieren soll, wenns nicht mal in der Simulation 
das N-Flag verändert. Hab heute in der früh auch noch kurz ein asl 
versucht. Aber der Assembler macht ein lsl daraus. Bin irgendwie 
verunsichert. Dachte, der Assembler "optimiert" nichts, und alles ist 
so, wie ich es eingebe... Wie kommt es, dass ich beim Debugen andere 
Befehle sehe, als die, die ich eingegeben habe?

Also die Moral von der Geschichte ist dann, wenn ich Dich recht 
verstehe, dass es mit einem MOV r1, r1, r1, LSL #16 funktionieren 
sollte, das N-Flag zu setzen, oder?

von Andreas K. (a-k)


Lesenswert?

> Also die Moral von der Geschichte ist dann, wenn ich Dich recht
> verstehe, dass es mit einem MOV r1, r1, r1, LSL #16 funktionieren
> sollte, das N-Flag zu setzen, oder?

Nein. Sondern mit MOVS.

von Peter Pippinger (Gast)


Lesenswert?

Vielen Dank! Werd ich heute abend gleich mal ausprobieren.

Hast Du vielleicht eine Idee, was das Problem mit dem Compiler betrifft, 
dass er zum einen den Code aus Bsp2 (von C) erzeugt und zum anderen 
scheinbar meine ASM-Befehle "optimiert"?

von Peter Pippinger (Gast)


Lesenswert?

Also fürs Protokoll:

mit MOVS r1, r1, LSL #16 wird das N-Flag richtigerweise gesetzt. Alles 
Super! Allerdings würde mich trotzdem noch interessieren, warum der IAR-
Compiler aus:

// ----------------------------------------------------------
// (C-Code):
// ----------------------------------------------------------

// CP - card present
while(((m_pPio->PIO_PDSR) & BIT15))
{
   /*put your card present event here*/
}

// ----------------------------------------------------------
// das hier macht (ASM):
// ----------------------------------------------------------

Next label is a Thumb label
// while(((m_pPio->PIO_PDSR) & BIT15)) { /*put your card present event 
here*/  }
  00000116  4823      LDR          R0, [PC,#0x08C]
                                   ; [0x1A4] =m_pPio (0x694)
  00000118  6800      LDR          R0, [R0, #0]
  0000011A  6BC0      LDR          R0, [R0, #60]
  0000011C  0400      LSL          R0, R0, #16
  0000011E  D4FA      BMI          0x000116

// ----------------------------------------------------------

Das kann doch so dann nie funktionieren, wenn das N-Flag nicht mit LSL 
gesetzt wird.

Kann da nicht jemand Licht ins Dunkle bringen? Ist doch ne berechtigte 
Frage, oder?

von Andreas K. (a-k)


Lesenswert?

Jetzt wird's klarer. Ich hatte mich schon länger über den Befehl LSL 
gewundert, denn genau genommen gibt's den im ARM Befehlssatz garnicht. 
Im Thumb Befehlssatz schon.

ARM: Ob die Flags gesetzt werden oder nicht entscheidet das "S" hinten 
am Befehl (=> Bit im Opcode), ausser bei CMP/CMN (ergibt ohne irgenwie 
wenig Sinn).

Thumb: Ob die Flags gesetzt werden oder nicht entscheidet die 
Befehlsreferenz. Nicht immer leicht zu durchschauen, weil sich ADD und 
ADD da unterscheiden.

All das lässt sich übrigens prima selber feststellen, wenn man mal das 
ARM ARM von vorne bis ungefähr zu Mitte durchliest und dabei nicht 
vergisst, die grauen Zellen zu aktivieren.

von Peter Pippinger (Gast)


Lesenswert?

Hallo Andreas nochmal,

das ist schön, dass es für Dich jetzt klarer ist.

Mir leuchtet das jetzt auch ein, dass das "S" angibt, dass die Flags 
gesetzt werden sollen.

Leider verstehe ich nicht, warum der Compiler Code erzeugt, der so wie 
er ist nicht lauffähig ist. Zumindest denke ich das, weil in der 
Step-by-Step Simulation läuft es nicht so, wie es laufen sollte.

Warum ist bei dem Board diese DEMO zu SD/MMC dabei, die man wunderbar in 
der IAR-Workbench öffnen kann, aber leider scheinbar keine brauchbare 
Binary erzeugt?

Es ist nicht so, dass ich nicht lernfähig, oder willig wäre, aber 
irgendwo ist man halt immer mal auf Hilfe angewiesen, wenn was nicht so 
funktioniert, wie man es gerne hätte. Zugegeben, wahrscheinlich könnte 
man länger schauen, und nach Fehlern suchen. Aber brauchbare Beispiele 
sollten halt schon vorhanden sein. Weil nur Theorie ohne Praxis ist - 
für mich zumindest - hartes Brot :-(

Wenn ich mir ein Buch kaufe, stehen dort doch auch viele praxisbezogene 
Beispiele drinnen. Das bringt mir persönlich mehr. Aber da ist jeder 
bestimmt ein bisschen anders veranlagt.

Mich würde es auf jeden Fall sehr freuen, wenn die Frage zum 
Compiler-Code noch so geklärt werden könnte, dass auch ich es verstehe 
:-)

von Andreas K. (a-k)


Lesenswert?

Was bringt dich zur Vermutung, dass der Compiler falschen Code erzeugt? 
Der im Posting von 20:25 wird so m.E. funktionieren.

Zeig mir bitte mal die Variante, die nicht funktioniert. Aber als 
Assembler-Listing mit Hex-Code drin, nicht nur den Quellcode.

von Peter Pippinger (Gast)


Lesenswert?

Ok. habe jetzt das ganze nochmals getestet. Es scheint im Thumbmode echt 
zu funktionieren :-)

Mein Problem ist folgendes:

Habe den C-Quelltext assemblieren lassen. Den erzeugte Assembler-Code 
habe ich dann in ein anderes Assembler-Projekt versucht eingefügt. An 
dieser Stelle macht der Assembler scheinbar keinen Thumb-Code mehr.
Beispiel:

aus:
  LSL          R0, R0, #16

wird:
  00000004  E1A00800  MOV          R0, R0, LSL #16

Muss ich beim Programmieren im Quelltext irgendwo vermerken, dass ab 
einer bestimmten Stelle Thumb-Code kommt.

Wenn ja - wie jann man das umstellen?

von Andreas K. (a-k)


Lesenswert?

Hier nix IAR, da kann ich nicht weiterhelfen.

von Peter Pippinger (Gast)


Lesenswert?

Ja, aber vielleicht komm ich ja drauf, wenn Du mir einfach sagst, wie es 
bei Dir funktioniert, ARM- und ThumbCode zu mischen.

Vielen Dank!

von Andreas K. (a-k)


Lesenswert?

.arm
.thumb

von Peter Pippinger (Gast)


Lesenswert?

Hallo NG,

habe wohl soeben geschafft, dass der Proz/Emulator in den Thumb-Mode 
springt. Ist das mit dem BX wirklich immer nötig, oder gibts auch noch 
andere Methoden, um zwischen den Modes zu switchen? Es wird auch 
tatsächlich das N-Flag gesetzt, wenn das Bit1 nach Bit31 gewandert 
ist...

main
  ADR R0, Into_THUMB
  BX R0

  CODE16

Into_THUMB

  MOV r0, #1

  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1

  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1

  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1

  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1
  LSL r0, r0, #1

von Andreas K. (a-k)


Lesenswert?

> Ist das mit dem BX wirklich immer nötig,

Wenn mit ARM7 (ARMv4) sowohl ARM- als auch Thumb-Code verwendet wird ja. 
ARM9 (ARMv5) wurde etwas erweitert, um die Nachteile, die durch durch 
dieses sogenannte "interworking" entstehen zu reduzieren.

von Dominic R. (dominic)


Lesenswert?

Erst ARM9E ist ARMv5, ARM9 ist wie ARM7 ARMv4. Das bedeutet dass z.B. 
der weit verbreitete AT91RM9200 ARMv4 ist (ARM920T Kern), während dessen 
Nachfolger, die AT91SAM926x Reihe, ARMv5 (ARM926EJ-S Kern) ist.

von Peter Pippinger (Gast)


Lesenswert?

Ok, vielen Dank für eure Antworten.

Um dieses Thema mal langsam zu schließen, hätte ich noch eine 
abschließende Frage:

Es sollte doch möglich sein, dem C-Compiler zu sagen, dass er keinen 
16Bit-Thumb-Code erzeugen soll, sondern 32Bit-ARM-Code, oder?

von Peter Pippinger (Gast)


Lesenswert?

Habs eben selber gefunden:

Projekt -> Options -> General Options -> Processor mode -> (x) Arm

von Andreas K. (a-k)


Lesenswert?

> Projekt -> Options -> General Options -> Processor mode -> (x) Arm

Wird halt langsamer dadurch, jedenfalls bei Atmels SAM7 im Flash bei 
voller Taktfrequenz, weil Atmels Flash zu schmalbandig ist. Durchsatz 
ist effektiv nur 16bit pro Takt.

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.