Forum: Compiler & IDEs lpc2129 GCC ISR-Verwaltung


von Andy (Gast)


Lesenswert?

Hallo zusammen,
auch wenn es jetzt auf den ersten Blick doof erscheint:
Braucht man beim ARM-GCC 4.1.1 für den lpc2129 in den Interrupt-Routinen 
die ENTRY und EXIT-Makros?
Beim Beispiel uart0_irq sind diese Makros noch im Code und beheben laut 
Kommentar ein Compiler-Problem. Das Beispiel blinkswitch_irq kommt 
hingegen ohne aus.

Ich habe jetzt beide Varianten ausprobiert und immer noch ein 
(ähnliches, aber nicht gleiches) Problem.
Eine ISR empfängt Daten von einem ENC28j60(uIP) und gibt die auf dem 
CAN-Bus 1 aus. CAN-Bus 2 empfängt die Daten und sollte sie in seiner ISR 
zur Kontrolle auf das UART ausgeben. Im Hintergrund läuft noch eine 
Timer-ISR mit ~500ms und die RTC-ISR (1s).
Kurz ETH->CAN->UART.
Wenn ich in der CAN-ISR sofort zurückspringe funktioniert das auch bei 
viel Verkehr einwandfrei. Auch die Ausgabe einzelner Zeichen über UART 
funktioniert sehr gut. Wenn die UART-ISR aber länger beschäftigt ist 
(getestet mit einfacher FOR-Schleife) und ich viele TCP-Pakete schnell 
sende, dann gibt es 2 Varianten:
Mit ISR_ENTRY() & Co bleibt der Controller anscheinend stehen (oder 
kreist im Nichts)
Ohne ISR_ENTRY() & ISR_EXIT() macht der Controller irgendwann einen 
Reset.

Innerhalb der ISR kann doch keine andere ISR aufgerufen werden, oder?

Bin mir derzeit nicht sicher, ob es an meinen ISRs, uIP oder ganz 
woanders liegt.

MfG Andreas

von Andreas K. (a-k)


Lesenswert?

Welche ENTRY/EXIT Macros? GCCs gibt es viele. GCC hat nach wie vor einen 
Bug bei Routinen, die via Compiler als Interrupt-Handler deklariert 
werden. Tritt nicht immer auf, steckt aber nach wie vor drin.

ARM und verschachtelte Interrupts: 
http://www.nxp.com/acrobat_download/applicationnotes/AN10381_1.pdf

von Andy (Gast)


Lesenswert?

Hallo & Danke für die Antwort!   ;)
Die AN zu den nested Interrupts kenne ich. Was mich an den 
ENTRY/EXIT-Makros verwundert hat ist, daß sie zum einen selbst nicht in 
allen Beispielen von WinARM benutzt werden und zum anderen laut 
Kommentar von 2004 sind. Seitdem könnte ja das Problem gelöst sein.

Wir ist das so schön nach Murphy: Kaum fragt man, schon findet man das 
Problem selbst. In diesem Fall waren es wohl weder die Interrupts noch 
uIP. Anscheinend hat WinARM ein Problemchen mit inline-Funktionen 
(verwendete Optimierung: s).
Ich habe mal die ganzen "inline" weggemacht und schon läuft es perfekt. 
Auch ohne ENTRY&EXIT. Kleine Ursache, große Wirkung.   :(

MfG Andy

von Andreas K. (a-k)


Lesenswert?

Merkregel: 99% aller Compilerfehler sitzen vor der Tastatur, nicht im 
Compiler.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Beim arm-elf gcc zumindest bis Version 4.1.x (habe mit 4.2.0 noch nicht 
viel gemacht) betrifft meines Wissens Code, der mit Interwork-Option 
compiliert wird und bei dem ISR mit dem interrupt function-attribute 
versehen werden. Die genannten Macros und Beispiele beziehen sich wohl 
auf die von mir bereitgestellten Beispielanwendungen. Daher ein paar 
Erläuterungen:

Wenn kein thumb/thumb-Interwork genutzt wird, also alles für den 
"ARM-mode" kompiliert wird, sehen die vom Compiler generierten Entry- 
und Exit-Codes für function-attribute interrupt korrekt aus. Wenn man 
auf interwork verzichtet, kann man also problemlos mit dem Attribute 
arbeiten. So wie im Beispiel "blinkswitch_irq" demonstriert.

Will man Probleme bei Verwendung von thumb/thumb-interwork vermeiden, 
verzichtet man am Besten auf das interrupt function-attribute und gibt 
die erforderlichen Sequenzen (Register auf den Stack retten, 
Programm-Counter anpassen) zu Beginn und Ende einer ISR "von Hand" vor. 
Dazu gibt es im Prinzip zwei Möglichkeiten:

- man weist den Compiler an, keinerlei Entry- und Exit-Code automatisch 
zu erzeugen, in dem man die ISR mit dem naked function-attribute 
versieht und den erforderlichen Anweisungen per Inline-Assembler 
einträgt. Am einfachsten mit zwei Makros mit Assembleranweisungen, die 
an passender Stellt eingesetzt werden. So wie im Beispiel "uart0_irq".

- Man lässt den Interrupt-Controller (VIC, AIC etc.) nicht direkt die 
ISR anspringen, sondern lässt den Core INT-Vector auf eine 
Assembler-Routine verzeigen, in der die notwendigen Vorbereitungen 
getroffen werden und dann erst in die eigentliche ISR verzweigt wird, 
beim Rücksprung erfolgen dann die "Nacharbeiten". So wie in diversen 
Beispielen von Atmel oder z.B. meiner Portierung der LPC213x/4x 
Beispiele von NXP auf 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/lpc2k_bundle_port/index.html

Die letztgenannte Lösung ist auch sehr brauchbar, wenn man den C-Code, 
auch bei "reinem" ARM-Code, nicht mit herstellerspezifischen 
Erweiterungen "verunstalten" will (attribute, pragmas, inline-assembler 
etc.). Die ISR kann man in C dann einfach "runterschreiben".

Inline-"Problemchen" sind mir beim arm-elf gcc 4.1.x (wie in den im 
Moment aktuellen Versionen meiner WinARM Sammlung enthalten) keine 
bekannt. Würde mich interessieren, was dahintersteckt. Gibt es ein 
Minibeispiel, an dem man das nachvollziehen kann?

Martin Thomas

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.