Autor Thema: ARM Timer-IRQ  (Gelesen 3902 mal)

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« am: 23. August 2013, 19:36 »
Hallo ,
im Moment beschäftige ich mit Timer-IRQ Raspberry Pi.
Leider hänge ich immer noch an der Grundlagenforschung fest.

Die nachfolgende Tabelle ist von Berry-Boot
nach dem Start vom OS ausgelesen.


00  060000EA  b address     28  0C1C81E3  ??
04  0000A0E1  mov r0 ,r0    2C  00209FE5  ldr r2 ,[r15]
08  0000A0E1  mov r0 ,r0    30  00F09FE5  ldr r15,[r15]
0C  0000A0E1                34  00010000
10  0000A0E1                38  00080000
14  0000A0E1                3C  00000000
18  0000A0E1
1C  0000A0E1
20  0000A0E3  mov r0,#0
24  4210A0E3  ??

Mich interessiert im Moment Zeile 24 und 28.
Leider habe ich noch keine passenden Befehle
bzw. Syntax gefunden.
Vielleicht kann ja Jemand helfen?

Gruß
Relbmessa

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 23. August 2013, 20:46 »
24 ist mov r1, #0x42
28 ist orr r1, r1, #0xc00
Aber warum schreibst du die Instruktionen in Big-Endian?
24 wäre 0xE3A01042 in C.

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 23. August 2013, 21:46 »
Hallo Vogtinator ,
Dank für die schnelle Antwort.
mov r1,#0x42 ok
orr r1,r1,#0xc00 nur halb , der wert 0xc00 ist wohl falsch?
bei mir kommt dann als Ergebnis : 031B81E3 raus .mh
werde noch ein wenig studieren :-P
Gruß
Relbmessa
PS
Verstehe deine Frage nicht?
Habe es so abgeschrieben, wie es bei mir auf dem Bildschirm steht.
C ist außerdem nicht mein Ding  :?
« Letzte Änderung: 23. August 2013, 21:50 von Relbmessa »

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 24. August 2013, 16:45 »
Es gibt mehrere Möglichkeiten, 0xc00 zu assemblieren. Immediate values dürfen maximal 0xFF sein, allerdings können sie nach belieben geshiftet werden. Um das zu bestätigen, probier mal mov r0, #0x1ff aus. Da 0x1ff nicht in die 32 bit der Instruktion reinpasst, gibts zwei Möglichkeiten den Wert in r0 zu bekommen:
mov r0, #0x1f LSL 4
orr r0, r0, #0xf
oder auch:
ldr r0, =0x1ff
was allerdings eine Abkürzung für folgendes ist:
.word wert=0x1ff (meistens in .text)
ldr r0, wert
Sollte der Wert aber, wie 0xc00 mit anderen Möglichkeiten in einem Befehl dekodiert werden können, gibts folgendes:
orr r1, r1, #0xc0 LSL 4
orr r1, r1, #0x0c LSL 8
orr r1, r1, #0x0c ROR 24
orr r1, r1, #0xc0 ROR 28
orr r1, r1, #0x0c ASR 24
orr r1, r1, #0xc0 ASR 28
Siehe http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Cihbeage.html

Welche nun dein Assembler nimmt, ist ihm überlassen.

Zitat
Verstehe deine Frage nicht?
Habe es so abgeschrieben, wie es bei mir auf dem Bildschirm steht.
C ist außerdem nicht mein Ding
Bei 4210A0E3 ist E3 das höchstwertigste Byte.
Du schreibst ja auch 100 und nicht 001 für hundert.

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 24. August 2013, 20:41 »
Danke für die schnelle und ausführliche Antwort.
Muss ich erst mal durcharbeiten.
Heute habe ich aber keine Zeit.

Gruß
Relbmessa
 

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 26. August 2013, 20:10 »
HalLo ,
mein rudimentäres Programm läuft. 8-)

Es wird ein Timer-IRQ erzeugt und ich kann wieder aus der ISR raus.

Meine Frage:
wenn ich Bit-7 vom CPSR  schon in der ISR lösche , dann hängt sich der Rechner auf.
Kann man das Bit-7 nicht in der ISR schon löschen (ist halt sinnvoll).
Oder mache ich vielleicht was Falsch?? :?
Hat einer ARM Erfahrung ? /Raspberry Pi  :roll:

Gruss
Relbmessa

« Letzte Änderung: 26. August 2013, 20:13 von Relbmessa »

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 26. August 2013, 22:59 »
 :-D
Problem erkannt:
der Timer feuert  in zu kurzen Abständen..
suche jetzt eine Möglichkeit  die Zeit richtig einzustellen. :-P



Gruß
Relbmessa

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 29. August 2013, 14:35 »
Ich aktiviere IRQs erst wieder, wenn ich aus dem Handler herausspringe.
subs pc, lr, #4 kopiert spsr ja wieder in cpsr. Da IRQs vor dem IRQ ja aktiviert waren werden sie so wieder aktiviert.
Wenn du es dem Prozessor ermöglichst, den IRQ-Handler während des IRQ Handlers aufzurufen, wirst du nie mehr zu deinem Programm zurückkehren können, da lr dann überschrieben wurde.

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 29. August 2013, 18:50 »
Hallo ,
der IRQ wird beim Auslösen im CPSR ausgeschalten.
Ich schalte in erst wieder ein wenn die ISR verlassen wird.
Wenn die ISR mehr Zeit braucht als die Auslösung des nächsten IRQs bekommt man natürlich ein Problem.

Im Moment bin ich noch bei der Grundlagen-Erforschung.
Ich wollte den Timer  (ARM -side ) benutzen, geht wohl aber nicht.
Ohne diesen zu aktivieren kommt schon ein periodischer IRQ .
Was Berryboot eingestellt hat muss ich erst noch prüfen.

Den IRQ erst nach dem Verlassen der ISR zu aktivieren ergibt bei meinen Programm keinen Sinn,
denn ich brauche eine konstante Wiederholung .

Ob das so geht ?   :evil:
Im Moment läuft das Programm stabil, aber der Interrupt-takt setzt periodisch aus.
Mal sehen, wo die Ursache zu suchen ist

Gruß
Relbmessa
.       
« Letzte Änderung: 29. August 2013, 19:59 von Relbmessa »

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 30. August 2013, 14:20 »
Nein, bloß nicht!
Wenn der IRQ zu schnell kommt schmierts ab.
Auch macht es keinen Sinn einen IRQ nur halb zu behandeln, was passiert wenn der interrupt ausgelöst wird während die CPU sich noch im Handler befindet.
Wenn der Handler mehr Zeit braucht als der IRQ ist deine CPU zu lahm für das, was du tun willst.
Ganz sicher, dass du nicht vergessen hast, den IRQ auch zu acken?

Svenska

  • Beiträge: 1 790
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 30. August 2013, 15:20 »
Hallo,

normalerweise (das heißt: höchstwahrscheinlich auch bei ARM so, habe ich aber nicht nachgeschlagen) wird das Interruptflag automatisch zurückgesetzt, wenn die CPU in eine ISR springt. Damit sind, während die CPU den Interrupt behandelt, alle Interrupts deaktiviert. Dieses Flag wird beim Verlassen der ISR auch automatisch wieder zurückgesetzt.

Eine ISR darf niemals Interrupts aktivieren, ohne ihren eigenen Interrupt vorher explizit abgeschaltet zu haben! (Nested Interrupts braucht man normalerweise nicht, das heißt also: Eine ISR sollte niemals Interrupts erlauben! Auch nicht am Ende!)

Wenn dein IRQ schneller feuert, als du ihn verarbeiten kannst, dann dauert deine ISR zu lange und du solltest dein Design überdenken. Je nach Komplexität der Hardware liest die ISR nur die Daten aus der Hardware, bereitet sie etwas auf (z.B. Skalierung, LUT), schreibt die Daten in einen globalen Puffer und weist das übergeordnete System (z.B. verantwortlicher Treiber, Kernel, Hauptprogramm) darauf hin, dass ein Interrupt stattgefunden hat. In einer ISR sollte nichts stattfinden, was länger als ein paar hundert Takte dauert.

Du darfst es natürlich auch anders machen, solltest dann aber verdammt gut begründen können, warum du es anders machen möchtest.

Gruß,
Svenska

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 30. August 2013, 19:51 »
Hallo ,
das Bit-7 im CPSR wird nach dem verlassen leider nicht zurück gesetzt.  :?
Ob es da noch andere Automatismen gibt kann ich nicht sagen.
Es muss leider zurück gesetzt werden.
Mein kleines Programm läuft jetzt stabil . :-D
Aber primär geht es mir darum die IRQ-Timerzeit einzustellen.
Der Timer (ARM-side) zeigt aber keine Wirkung.Nur derTimer- IRQ kann im Control-Register beeinflusst werden (offset 0x408 BCM2835 ARM Peripherals).
Welcher Timer-Wert  im Moment jetzt tickt ?? (keine Ahnung)
 Ich suche weiter!

Gruß
Relbmessa
 

Svenska

  • Beiträge: 1 790
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 30. August 2013, 20:53 »
Hallo,

das Bit-7 im CPSR wird nach dem verlassen leider nicht zurück gesetzt
Kurzes Googlen führt ins hauseigene Wiki (hierhin) und erzählt folgendes:
- Wenn ein IRQ auftritt, werden R15 (PC) nach R14 und CPSR nach SPSR gesichert.
- In CPSR wird das I-Flag deaktiviert, d.h. IRQs abgeschaltet, und dann in die ISR gesprungen.
- Zur Rückkehr muss man SPSR nach CPSR kopieren (d.h. die Flags wiederherstellen) und R14 nach R15.
Das macht man bei einem IRQ mit "subs r15, r14, #4", bei anderen Exceptions mit anderen Befehlen.

Und dann sind IRQs auch wieder an, wenn sie vorher an waren.

Dein Problem wird sein, dass du nicht sauber aus der ISR zurückkehrst und darum bei jedem IRQ die Flags verlierst.

Viel Erfolg,
Svenska

Vogtinator

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 30. August 2013, 21:33 »
Bei anderen Exceptions mit dem selben Befehl, aber anderem op2.
#8 bei Data Abort, #4 bei FIQs u. IRQs und #0 bei Prefetch Abort und Undefined instruction.
Wegen der Pipeline muss man ggf. eine oder zwei Befehle abziehen, das S-bit des Befehls kümmert sich darum,
dass mov cpsr, spsr GLEICHZEITIG stattfindet.
Mit einem Debugger kannst du ja mal an 0x18 einen Breakpoint setzen und dir SPSR anschauen.

Edit:
Zitat
- Wenn ein IRQ auftritt, werden R15 (PC) nach R14 und CPSR nach SPSR gesichert.
Genauer: lr des Prozessormodus. Bei IRQ R14_irq, bei FIQ R14_fiq, bei Undefines Instruction R14_und usw.

Zitat
- In CPSR wird das I-Flag deaktiviert, d.h. IRQs abgeschaltet, und dann in die ISR gesprungen.
Und bei FIQs zusätzlich noch FIQs abgeschaltet.
« Letzte Änderung: 30. August 2013, 21:35 von Vogtinator »

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 30. August 2013, 23:18 »
Danke Leute ,
dass mit dem Rücksprung habe ich schon gelöst.

Wie gesagt, es geht mir primär um die Zeit Einstellung vom Timer.
Ich habe festgestellt das der System Timer den IRQ auslöst.
Muss nur noch rauskriegen wie das ganze eingestellt wird.

Danke

Gruß
Relbmessa
   

 

Einloggen