Hallo, ich habe folgendes Problem. ich arbeite mit dem QNX Betriebssystem für einen embedded PowerPC (e300 Core). Nun muss ich eine Interrupt Routine für den UART machen. Mein Problem ist, dass ich nicht weiß welche Register der Compiler alle verwendet. Der Compiler basiert auf GCC 2.95.3, ich weiß dass es irgendeine Festlegung geben muss welches Register wofür verwendet wird, leider finde ich aber keine Übersicht. r1 wird wohl als Stackpointer missbraucht, aber über die anderen finde ich nichts. Vielleicht sinds ja nur 2 oder 3 Register die ich retten muss und nicht gleich alle...
@ MasterFX (Gast) >einen embedded PowerPC (e300 Core). Nun muss ich eine Interrupt Routine >für den UART machen. Mein Problem ist, dass ich nicht weiß welche >Register der Compiler alle verwendet. Der Compiler basiert auf GCC Das geht dich als normalen C-Programmierer auch gar nichts an. Das macht der Compiler selber. Du hast nur Zugriff auf Variablen. Und das reicht auch, erst recht für den UART. MFG Falk
Dann wüsste ich aber gerne wie ich eine InterruptRoutine programmiere. So wie es es nämlich sehe geht das weder mit Pragma noch mit __attribute__((interrupt("IRQ"))) wie es bei ARM der Fall ist. Zudem, wenn es mich nichts angehen würde, dann wüsste ich doch zu gerne woher ich hätte wissen sollen, dass r1 für den Stack verwendet wird. Außerdem muss ich am Anfang in Assembler programmieren.
@ Timmo H. (masterfx) >Dann wüsste ich aber gerne wie ich eine InterruptRoutine programmiere. Gibst da keine Doku oder Beispiele? >Außerdem muss ich am Anfang in Assembler programmieren. Warum? MFG Falk
Naja weils wohl nicht anders geht. Mit C hat man nunmal keinen zugriff auf die DBATs und anderen CPU Register. Der e300 Core hat da so gewisse Eigenheiten. Zudem ist der Resetvektor nicht gerade groß und wie jeder weiß blähen Compiler gerne den Code auf. Auch die Leute die den Uboot für den Core Programmiert haben arbeiten anfangs mit Assembler. Leider ist es nirgends dokumentiert, da QNX sich bei der Doku auf die QNX-Funktionen Bezieht, aber ich mache ja den Bootloader und da ist noch nichts mit QNX.
Gerade in der GCC Newsgroup gefunden: >>>>> Jeroen writes: > I have a question regarding the interrupts on the PowerPC platform. Is it > possible to let the compiler know some function is an interrupt handler? I > read the documentation and saw things like __attribute((interrupt)) but > these options only applied to certain platforms and where not for > PowerPC. The PowerPC port of GCC does not provide any special features for functions that will be used as interrupt handlers. One can use the generic features of GCC, but the PowerPC target of GCC does not adjust its behavior specifically for interrupt handlers. David Tja, von wegen das macht alles der Compiler...
Hab nochmal ein wenig rumdebuggt und da werden echt viele Register verwendet. Ist praktisch alles von r0-r10 und r20-r31 dabei. Das ist echt mist. sind ja dann quasi mindestens 96 Bytes die ich mir auf den Stack hauen muss. Zudem würde der Vektor nichtmal für das Retten und Wiederherstellen der Register reichen, zumindest nicht mit einzelbefehlen. Link Register und Control Register kommen ja auch noch dazu. Irgendwie speichert dieser blöde PowerPC noch nichtmal die Rücksprungadresse in der InterruptRoutine. Denn wenn ich dort nur rfi rein schreibe springt er scheinbar immer wieder zum resetvektor. Echt seltsam.
So habs jetzt hinbekommen. Für diejenigen die es interessiert:
1 | . = 0x500 #External Interrupt |
2 | #-----Register absichern----- |
3 | stwu %r1, -32(%r1) #Neuer Stack-Frame |
4 | stw %r0, 0(%r1) #r0 Register speichern |
5 | mfcr %r0 #Condition Reg. auslesen |
6 | stw %r0, 4(%r1) #Condition Reg. speichern |
7 | mflr %r0 #Link Register auslesen |
8 | stw %r0, 8(%r1) #Link Register speichern |
9 | stw %r13,12(%r1) #r13 sichern |
10 | |
11 | |
12 | #--Ende Register absichern--- |
13 | |
14 | bl extern_interrupt_ISR #Zur C-Funktion springen |
15 | |
16 | #-----Register wiederherstellen----- |
17 | lwz %r13, 12(%r1) |
18 | lwz %r0, 8(%r1) |
19 | mtlr %r0 |
20 | lwz %r0, 4(%r1) |
21 | mtcr %r0 |
22 | lwz %r0, 0(%r1) |
23 | addi %r1,%r1,32 #Stack wiederherstellen |
24 | #---Ende Register wiederherstellen-- |
25 | rfi |
Ob es reicht nur die obigen Register zu retten weiß ich nicht, aber abgeschmiert ist er bis jetzt noch nicht
Ok, ich habe gerade festgestellt, dass es scheinbar nicht reicht. r9,r11 und r31 müssen auch noch gespeichert werden. Aber selbst das reicht wahrscheinlich nicht. Es muss doch irgendwo beschrieben stehen welche Register alle zu retten sind. Ich meine die Leute die den Compiler basteln müssen doch irgendwo mal was festgelegt haben. Oder bin ich der einzige der Interrupts auf einem PowerPC verwendet?
So ich denke ich habs jetzt gefunden. Da hier scheinbar niemand wusste wo es steht hier die Links: http://refspecs.freestandards.org/elf/elfspec_ppc.pdf http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF77852569970071B0D6/$file/eabi_app.pdf
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.