Hallo, Ich arbeit mir dem EvalBoard ADUC7026 - ARM Prozessor. Der unten angehängte code löst einen Interrupt jede 5µs (200kHz) auf. Dabei wird an ein Pin (P4.3) gesetzt und gelöscht und am Oszi angeschaut. Im main sind einfach die Configs gesetzt für den Interrupt und auch hier wird ein anderer Pin (P4.2) gesetzt und gelöscht um am Oszi zu erkennen, wie lange der Interrupt eigentlich braucht. Mein egentliches Problem: Man sieht am Oszi ganz gut wie der Pin (P4.2) im main mal ein und ausgeschaltet wird bis zum Interrupt, danach ist zu erkennen, dass der Interrupt ganze 1.6µs braucht um den Pin P4.3 zu setzen. Nach dem löschen braucht er wieder 1µs zum main zu sprigen. Obwohl ich einen Fast Interrupt reQuest verwende hat sich an der latency nichts verändert. Weiß vielleicht jemand warum es so lange dauert? Oder wie man die interrupt latency verbessern könnte? Danke im voraus! Gruß
Beim ARM7 muss man üblicherweise Interrupt-Handler Funktionen als solche kennzeichnen. Und zwar unterschiedlich je nachdem ob IRQ oder FIQ. Andernfalls kann es Most im Hauptprogramm geben. Dazu kommt, dass beim ARM7 Interrupt-Funktionen immer native ARM-Funktionen sind, keine Thumb-Funktionen. ARM-Funktionen laufen beim ADuC7000 im RAM deutlich flotter als im ROM. Such mal beim Compiler, wie man Funktionen ins RAM legen kann. Erheblich schneller geht es mit einem FIQ-Handler in Assembler, weil dann die Adressen und Werte nicht erst im Handler geladen werden müssen, sondern in den separaten Registern vom FIQ-Kontext schon vorbesetzt werden können. Zudem entfällt dann der bei FIQs ziemlich hässliche Overhead durch den Compiler. In C wird der FIQ oft überhaupt nicht schneller sein als der IRQ. Wenn der Compiler aus lieber Gewohnheit die Register ab R0 zuerst verwendet, der FIQ-Kontext aber erst bei R8 anfängt, so dass die verwendeten Register so oder so gesichert werden müssen. M.a.W: Der FIQ bringt nur bei Handler in Assembler wirklich Vorteile.
Hallo,
benütze mal sowas
void FIQ_Routine (void) _attribute_ ((interrupt("FIQ")));
void FIQ_Routine (void)
{
...
}
statt einer normalen Funktionsdeclaration
falls es dein Compiler zulässt
Gruss Klaus
Hallo, der Compiler gibt zwar keine Fehler aus, jedoch macht der Code nicht mehr das was er eigentlich machen soll. Ich habe gar keine output mehr. Wenn ich GP_TIMER_BIT auskommentiere funktioniert zwar die main, aber ein Interrupt wird nicht ausgelöst. gruß
Hallo,
schau Dir mal deine crt.s (die startup Routine) genau an und vergleiche
sie eventuell mit anderen die du im Netz findest.
die Adresse der FIQ Routine sollte bereits dort in den _vectors
auftauchen z.B. so :
_start:
# Exception Vectors
_vectors: ldr PC, Reset_Addr
ldr PC, Undef_Addr
ldr PC, SWI_Addr
ldr PC, PAbt_Addr
ldr PC, DAbt_Addr
ldr PC, ReservAddr /* Reserved Vector (holds Philips ISP sum) */
ldr PC, [PC,#-0xFF0] /* see page 71 of "Insiders Guide to the
Philips ARM7-Based Microcontrollers" by Trevor Martin */
ldr PC, FIQ_Addr
Reset_Addr: .word Reset_Handler /* defined in this module below */
Undef_Addr: .word UNDEF_Routine /* defined in main.c */
SWI_Addr: .word SWI_Routine /* defined in main.c */
PAbt_Addr: .word UNDEF_Routine /* defined in main.c */
DAbt_Addr: .word UNDEF_Routine /* defined in main.c */
IRQ_Addr: .word IRQ_Handler /* defined in main.c */
ReservAddr: .word 0 /* rounds the vectors and ISR addresses to
64 bytes total */
FIQ_Addr: .word FIQ_Routine /* defined in main.c */
Obige Sequenz stammt aus einem meiner Projekte und ist für einen LPC2148
von NXP, auch ein ARM7 Prozessor, und läuft bestens
Gruss Klaus
Hallo,
die startup Routine ist so ziemlich gleich.
Ich hebe jetzt mal den Tipp von A. K. befolgt und gefunden wie man die
IRQ-Funktion ins RAM ablegt und von dort abruft.
void IRQ_Function (void) _attribute_ ((interrupt ("IRQ")))
_attribute_ ((section (".ram_func")));
Das hat jetzt viel gebracht. Interrupt wird viel schneller abgearbeitet.
Jedoch habe ich das Problem. Wenn ich variablen außerhalb meiner IRQ
funktion definiere, z.B. als
int Index;
dann kann die Funtion damit nichts anfangen. Wenn ich sie innerhalb der
IRQ-Funktion definiere, kann es zwar damit arbeiten aber dann habe ich
Problem, dass es immer wieder neu initialisiert wird.
Gruß
Achte auf "volatile": http://www.mikrocontroller.net/articles/Interrupt#Wichtige_Eigenschaften_von_ISRs > dann kann die Funtion damit nichts anfangen. Wie äussert sich das?
Hallo, volatile habe ich schon probiert gehabt. Leider ohne Erfolg. Danke für den Link.
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.
