Forum: FPGA, VHDL & Co. Microblaze Interrupt-Overrun


von Philip K. (philip_k)


Lesenswert?

Hallo,

ich habe einen MicroBlaze, der Zyklisch einen externen Interrupt bekommt
und daraufhin ein bisschen Arbeit verrichtet. Jetzt kommt es unter
bestimmten Umständen vor, dass die IRQ-Handler Laufzeit größer wird als
die Zykluszeit, d.h. während noch gearbeitet wird, kommt der nächste
Interrupt. Ich weiß, das sollte nicht passieren...was ich aber nicht
weiß, ist wie der MB eigentlich mit der Situation umgeht. In der
Simulation sieht es so aus, als würden einfach Interrupts ignoriert, in
der Realität schmiert der MB ab. (Es kann natürlich sein, dass das in
der Simulation auch passiert, wenn sie lang genug läuft)
Kann mir jemand sagen, was in so einer Situation im MB passiert(wenn sie
laufend auftritt)? Ich kann in der Simulation zumindest sehen, dass die
laufende ISR nicht unterbrochen wird. Aber wird der IRQ tatsächlich
verworfen oder gibt es da sowas wie eine queue und es kommt irgendwann
zu einem Stack-Overflow?

von Klaus F. (kfalser)


Lesenswert?

Das Ganze hängt nicht nur vom Microblaze ab, sondern vom Zusammenspiel 
von Prozessor, Interrupt Controller, Interrupt Quelle, Konfiguration und 
Software.

Der Prozessor selbst selbst hat nur einen Interrupt Eingang, und ist nur 
pegelabhängig, d.h. solange der Pin aktiv ist, wird die Interrupt 
Routine angesprungen.
Im Normalfall, und wahrscheinlich auch in Deinem Fall, hat man einen 
Interrupt Controller vorgeschalten, der mehrere Quellen verwaltet und 
auch den Int-Pin des MB ansteuert.
Kommt ein externer Interrupt, dann wird der Int-Pin des MB aktiviert und 
die Interrupt Routine startet (falls Interrupts nicht gesperrt).
Die IRQ Routine ist nun dafür verantwortlich den IRQ-Controller zu 
quittieren, sodass dieser das Int-Pin zurücksetzt und dass dieser weiß, 
dass die anliegenden Interrupt behandelt wurden.

Erfolgt diese Quittierung am Anfang der Interrupt Routine, dann ist der 
IRQ-Controller wieder bereit für den nächsten Interrupt und würde den 
Int-Pin des MB wieder auf aktiv legen, sobald ein IR kommt.
Der MB reagiert normalerweise darauf noch nicht, er ist ja noch in der 
IRQ Routine und die IRs sind gesperrt.
Der IRQ-Controller aber speichert den 2. IRQ und in diesem Sinn hätte 
man eine Art "Queue" für Interrupts. Alle weiteren gehen aber verloren.

Normalerweise quittiert man den IRQ-Controller aber erst am Ende der IRQ 
Routine, sodass alle IR während der IRQ Routine verloren gehen.

Ein Stack Overflow kann nur dann auftreten, wenn man in der IRQ Routine 
die Interrupt wieder aktiviert.
Nur dann kann wird nämlich die IRQ Routine nicht fertig abgearbeitet, 
sondern bei Eintreffen eines weiteren IR neu aufgerufen.

von Philip K. (philip_k)


Lesenswert?

Klaus Falser schrieb:
> Im Normalfall, und wahrscheinlich auch in Deinem Fall, hat man einen
> Interrupt Controller vorgeschalten, der mehrere Quellen verwaltet und
> auch den Int-Pin des MB ansteuert.
So ist es.

> Normalerweise quittiert man den IRQ-Controller aber erst am Ende der IRQ
> Routine, sodass alle IR während der IRQ Routine verloren gehen.
So mach ichs.

> Ein Stack Overflow kann nur dann auftreten, wenn man in der IRQ Routine
> die Interrupt wieder aktiviert.
> Nur dann kann wird nämlich die IRQ Routine nicht fertig abgearbeitet,
> sondern bei Eintreffen eines weiteren IR neu aufgerufen.
Dann muss es wohl andere Gründe für meinen Absturz geben. Vielleicht hat 
ja jemand einen Tipp, wie man solchen Fehlern auf die Schliche kommt?

von Klaus F. (kfalser)


Lesenswert?

Philip K. schrieb:
> Vielleicht hat
> ja jemand einen Tipp, wie man solchen Fehlern auf die Schliche kommt?

Debugger?

von Holger H. (holger-h-hennef) Benutzerseite


Lesenswert?

Hat der auch #pragma und damit RETI Opcode drin ?
STACKSIZE 4Byte.
Can YOU MAKE A CALL AND A CALL AND A CALL ON A CALL ???

Ich such noch das Youtube Vid. von dem JULIUS BAXTER aus Australien,
(UNI CAMBRIDGE) Heisst CHIPHACKS.
Der Teil fängt mit dem Satz an Could it be worster, da zeigt der
den FreshMans was da so geht. Sowas habt ihr noch nicht gesehen, wie der
mit dem System da rumspielen kann. Einfach mit Command Interface und
Linux oder was noch dolleres. Der hat auch ein eigenes Repository.
Da zeigt der mit GTK Wave wie er das Teil debuggen kann, und auch
die STACK SIZE hochsetz für IRQ.
Sonst geht der in die Binsen.

Gruss Holger.

D.H vor dem RETI kommt der IRQ-ACK mit clear irq_flg_reg via Null oder
1 z.B Atmel hat 1, PIC hat 0.

also clr IRQ ist der letzte Befehl, und nicht noch was dazwischen
machen. Damit weiss die MCU ok der irq is ended, u. dann kommt der RETI;
Und ich hatte RET im Code, weil ich das olle #pragma nicht machte.
Der Strommesser ging hoch und ich habe nur noch ???? gemacht.
BastelTip:
Aber mit dem Trick kann man noch den "WDOG" testen, der den RESET macht.

: Bearbeitet durch User
von Philip K. (philip_k)


Lesenswert?

Klaus Falser schrieb:
> Philip K. schrieb:
>> Vielleicht hat
>> ja jemand einen Tipp, wie man solchen Fehlern auf die Schliche kommt?
>
> Debugger?

Ich muss gestehen, dass ich wenig Erfahrung mit dem debuggen von 
embedded CPUs habe. Was ist denn zum Beispiel, wenn es sich um einen 
Seg-Fault handelt. Der wird ja ohne ein OS nicht abgefangen. Kann ich 
sowas überhaupt mit nem Debugger nachvollziehen?

von Holger H. (holger-h-hennef) Benutzerseite


Lesenswert?

Also "nicht" so machen..

Irq_routine

.....

.....

IRQ ACK und dann noch dahinter dem ACK Code ...

BLUB();
BLA();


....
RETI;
#######

Ein guter Compiler kann das abfangen ?

Aber beim editieren passiert das eben, das der IRQ-ACK noch oben
"edited" wird. Ich habe das schon oft genug in Source Code gesehen.

--------------------------------------

Meinetwegen das IRQ- is doubble buffered.
Dann kann man die CPU so mit IRQ:S beharken, dass die nicht mehr zur
main Routine kommt.
Kann man mal mit sonem ollen 8 Bitter AT90232 testen, in wie weit der 
das mitmacht.
Da hatte ich auch die Stack-Size so klein, und das ging nicht so
richtig, bis ich die hochgestzt hatte. Und ich nur ?????.

Gruss Holger.

von Klaus F. (kfalser)


Lesenswert?

Philip K. schrieb:
> Was ist denn zum Beispiel, wenn es sich um einen
> Seg-Fault handelt. Der wird ja ohne ein OS nicht abgefangen. Kann ich
> sowas überhaupt mit nem Debugger nachvollziehen?

Einen Segmentation Fault kann man beim MicroBlaze nicht haben, weil der 
keinen virtuellen Speicher und keine Memory Management Unit (MMU) hat 
:-).
Macht die Sache leichter!
Mit dem Debugger kann man halt nachschauen, in welchen Programmteil die 
CPU grad steckt (Interrupt Routine usw).
Du schreibst Absturz, aber wie äußerst sich das?
Gibt es Programmteile die noch funktionieren, LEDs die Blinken usw.

Holger Harten schrieb:
> Dann kann man die CPU so mit IRQ:S beharken, dass die nicht mehr zur
> main Routine kommt.

Das trifft für jede CPU zu, wenn zuviele Interupts kommen, das hat mit 
der Behandlung und dem Quittieren der IRQs nichts zu tun.
Und der Zeitpunkt des Quittierens hat zumindest beim MB keinen Einfluss 
darauf, ob die Int's korrekt abgearbeitet werden.
Solange die Interrupts für die ganze Zeit der ISR disabled bleiben, kann 
nichts passieren.
Dann wird die ISR komplett beendet, die CPU springt mit RETI zurück, die 
Interupts werden wieder enabled und die nächste ISR wird halt sofort 
ausgeführt -> Kein Stack Overflow.
Auch kein Absturz, sondern nur eine Überlastung der CPU.

von Holger H. (holger-h-hennef) Benutzerseite


Lesenswert?

Philip K. schrieb:
> Simulation sieht es so aus, als würden einfach Interrupts ignoriert, in
> der Realität schmiert der MB ab. (Es kann natürlich sein, dass das in
> der Simulation auch passiert, wenn sie lang genug läuft)
> Kann mir jemand sagen, was in so einer Situation im MB passiert(wenn sie
> laufend auftritt)? Ich kann in der Simulation zumindest sehen, dass die
> laufende ISR nicht unterbrochen wird. Aber wird der IRQ tatsächlich
> verworfen oder gibt es da sowas wie eine queue und es kommt irgendwann
> zu einem Stack-Overflow?

Evtl kannst du mal testen ob du den Master IRQen in der IRQ Routine
noch sofort im irq_entry disablen kannst.
Und damit mal dich selbst
für den next irq aussperren kannst.
Somit testest du einen Irq Umlauf, und einen RETÍ , und back to main()
Der next Trigger sollte dann keinen IRQ mehr auslösen.
Aber Ausnahme dabei ist die ZILOG EZ8 Encore.
Ist halt keine DIN Vorschift wie bei Schrauben, jeder macht da was der
will, bzw. kann.
Motorola 6809 die DatenBlätter sind exact gemacht, sowas geht heute
wohl nicht mehr bei machen Herstellern . Einfach schade. Und der 
Simulator ist nicht die 'STEP B Nummer virtuelles Silicon.
Und so sucht man halt mit dicke ????

#######################################################################

Lösung 2)
Im entry in die IRQ_Routine machst du das spezielle.bit für diesen 
irq_en
einfach auf disable. bing.off
Dann dein 'Irq_gedönse......
Wie nach meinem Schema vor dem RETI machst du das spezielle.bit
wieder auf enable. bing.on und dann IRQ-ACK und .... RETI.
-----------------------------------------------------------------------
Bei dem Zilog EZ8 Encore habe ich das so gemacht, weil sonst der IRQ
da zwei mal gefeuert hat.
Ging halt nicht anders zu machen. ()Interface_serieller Rx Port.
Kommt der character da zwei mal reingeschneit und du ????? häää
wie geht das ?.

Danach hatte ich das Problem gelöst.
#######################################
Das Master-Disable IRQ in der eigentlichen IRQ Routine hat bei dem
ZILOG EZ8 nicht gewirkt.
Also konnte man sich nicht in der IRQ Routine
dem Master IRQ killen.

Beim Altmel ging das aber.
D.h ist da immer der sez. Hersteller der CPU, und die Rev# Mask
bzw. Spec. zu holen.

Was ich mich nur so frage, warum lügt der Simulator ????
Kann der nicht das
Timing oder dynamische Timing in seinem SimCode da machen.
------------------------------------------------------------------------ 
---
Gruss Holger.

-------------------- 
-----------------------------------------------------
Da habe ich noch ein <tTip also read modyfy write in der IRQ Ack Routine
is was anderes als ein simpler store auf z.B Null.
D.h wenn du mehrere IRQ enabled hast, muss ja auch ein read modifiy
------------------------------------------------------------------------ 
--

von Holger H. (holger-h-hennef) Benutzerseite


Lesenswert?

Lösung 3 )
Was hast du für ein Board ?<

Eigentlich kann man da mit dem SDK und dem genau passenden
 BSP Bord Support Package eine nette App. zusammenklicken.
Das RS232 ist IRQ geladen. Netware ... usw. Ext IRQ.

Und wenn das geht. Geht man hin und moddet was neues noch dazu.
So kann man dann testen...
Geht mein Modell noch... nach dem mod.
Fazit: Evtl. Stack Size ermittelt bekommen.
Oder sonst was man halt als eigener Erbauer einer Architektur nicht
hinbekommt.
Das Tool-Pack aber besser kann, als man selbst.
Also von innen aufbohren. Also Hirnrissig denken...

Der Simulator ist ja dann für die Katz.
########################################################################
Gruss Holger.

von Holger H. (holger-h-hennef) Benutzerseite


Lesenswert?

Klaus Falser schrieb:
> Das trifft für jede CPU zu, wenn zuviele Interupts kommen, das hat mit
> der Behandlung und dem Quittieren der IRQs nichts zu tun.
> Und der Zeitpunkt des Quittierens hat zumindest beim MB keinen Einfluss
> darauf, ob die Int's korrekt abgearbeitet werden.
> Solange die Interrupts für die ganze Zeit der ISR disabled bleiben, kann
> nichts passieren.
> Dann wird die ISR komplett beendet, die CPU springt mit RETI zurück, die
> Interupts werden wieder enabled und die nächste ISR wird halt sofort
> ausgeführt -> Kein Stack Overflow.
> Auch kein Absturz, sondern nur eine Überlastung der CPU.

Danke so sehe ich das auch. Und somit kann ist das halt sicher.
Nur hatte ich mich wegen der Sequenz mit dem IRQ-'ACK sorgen gemacht,
weil ich den IRQ-'ACK halt immer ganz nach unten setze, also genau
in der Ablauf-Sequenz vor den "RETI", wiel es eben sequenziell im
C-Code da abgeht. Und somit ist das halt noch logischer,
aber wenn das natürlich bei der MB egal is, dann wird das wohl alleine
der "RETI" machen.
-----------------------------------------------------------------------
Ich habe das halt mit dem IRQ-'ACK am ENDE halt lieber.
-----------------------------------------------------------------------
Dabei könnte man sich sogar eine X-END_IRQ_ACK() Funktion schreiben,
die nur ein Port-Bit toggelt, und dann mit den Scope das mal messen,
wie die Tick-Zeit-Abstände im laufenden Prozess sind.
-----------------------------------------------------------------------
Halt wie ein WDOG-IRQ-Monitor für arme.
-----------------------------------------------------------------------
Danke Klaus.

Gruss Holger.

Also der ZILOG Z8 Encore hat für den IRQ noch den ATM Befehl, gemacht.
ATM is atomic für z.B volatile 16 Bit timer variablen.
-----------------------------------------------------------------------
Und so ein Modell is halt atomic, und die flags wollen richtig bedient
werden. So sehe ich das halt ... kann lieber zweimal nach, als nachher
wieder so häää ???? vor mir zu haben, wenn das Modell später zicken 
macht.
------------------------------------------------------------------------ 
-

Wenn die overclocking-Rate eben hoch genug ist kann man sich evtl nur
einmal im Jahr via Zufall einen Sys-Abbort leisten.

: Bearbeitet durch User
von Philip K. (philip_k)


Lesenswert?

Klaus Falser schrieb:
> Einen Segmentation Fault kann man beim MicroBlaze nicht haben, weil der
> keinen virtuellen Speicher und keine Memory Management Unit (MMU) hat
> :-).
Ok, das war der falsche Ausdruck. Aber auch beim MB kann ich irgendwo 
hin schreiben wo ich es eigentlich nicht will/darf.

> Du schreibst Absturz, aber wie äußerst sich das?
> Gibt es Programmteile die noch funktionieren, LEDs die Blinken usw.
Der MB macht (nach außen) gar nichts mehr und auch die UART-Verbindung 
ist tot.

von Klaus F. (kfalser)


Lesenswert?

Philip K. schrieb:
>> Du schreibst Absturz, aber wie äußerst sich das?
>> Gibt es Programmteile die noch funktionieren, LEDs die Blinken usw.
> Der MB macht (nach außen) gar nichts mehr und auch die UART-Verbindung
> ist tot.

Nun, das Fehlersuchen kann Dir niemand abnehmen und ohne mehr 
Information kann wahrscheinlich niemand helfen.
Tips:
- Kontrolliere, ob in der ISR große Felder angelegt werden. Das braucht 
Stack.
- Kontrolliere, ob in der ISR und den aufgerufenen Unterroutinen die 
Interrupts garantiert nicht freigegeben werden.
Das kann z.B. beim Verlassen von Critial Sections passieren, wenn diese 
mit
1
  microblaze_disable_interrupts();
2
  // Critical section 
3
4
  microblaze_enable_interrupts();
umschlossen werden.
- Vielleicht wird der Interrupt nicht korrekt gelöscht und immer wieder 
in Sequenz aufgerufen.
- Programm abspecken, bis es funktioniert.
-

Sonst müsstest Du einmal das Programm posten, vielleicht sieht jemand 
etwas.

von Philip K. (philip_k)


Lesenswert?

Klaus Falser schrieb:
> Nun, das Fehlersuchen kann Dir niemand abnehmen ...
Schon klar, das wollte ich auch niemandem antun:-)

> Tips:..
Genau sowas wollte ich. Ich habe an der Stelle halt wenig Erfahrung und 
wollte wissen, was so einen Aufhänger prinzipiell verursachen kann und 
wo man anfangen könnte zu suchen. Das mit dem Overrun war nur eine erste 
Idee, weil das Problem eben offenbar dann auftritt, wenn die ISR-Zeit 
länger wird als die Trigger-Zykluszeit.

: Bearbeitet durch User
von Philip K. (philip_k)


Lesenswert?

Ist es denn eigentlich tatsächlich nötig die Interrupts explizit in der 
ISR zu disablen/enablen oder macht das der darunterliegende Handler von 
Xilinx?

von Klaus F. (kfalser)


Lesenswert?

Philip K. schrieb:
> Ist es denn eigentlich tatsächlich nötig die Interrupts explizit in der
> ISR zu disablen/enablen oder macht das der darunterliegende Handler von
> Xilinx?

Solche Informationen finden man im Handbuch.
Auszug aus Version Microblaze Reference Guide 7.20 :

1. On an interrupt, the instruction in the execution stage completes 
while the instruction in the decode stage is replaced by a branch to the 
interrupt vector (address 0x10). The interrupt return address (the PC 
associated with the instruction in the decode stage at the time of the 
interrupt) is automatically loaded into general purpose register R14. In 
addition, the processor also disables future interrupts by clearing the 
IE bit in the MSR. The IE bit is automatically set again when executing 
the RTID instruction.

Übrigens habe ich gelogen:
Der Microblaze kann virtuelle Adressen und MMU haben.
'tschuldigung

von Philip K. (philip_k)


Lesenswert?

Klaus Falser schrieb:
> Solche Informationen finden man im Handbuch.
Dann beantrage ich hiermit die Schließung aller Internetforen...wenn eh 
alles irgendwo steht ;-)

Wenn ich das richtig verstehe(Ich kämpfe manchmal etwas mit der 
englischen Sprache), kann ich mir also explizites disablen/enablen 
sparen.

von Klaus F. (kfalser)


Lesenswert?

Philip K. schrieb:
> Wenn ich das richtig verstehe(Ich kämpfe manchmal etwas mit der
> englischen Sprache), kann ich mir also explizites disablen/enablen
> sparen.

Nicht nur sparen, sondern es ist auch sehr empfehlenswert es nicht zu 
tun.
Wie der MB in Zusammenhang mit dem internen Piplining genau reagiert ist 
nicht einfach herauszufinden, aber im Prinzip könnte es passieren dass 
wenn man kurz von der "Return from Interrupt" Anweisung die Interrupts 
freigibt, der Prozessor diese RTID Anweisung gar nicht ausführt, sondern 
sofort nochmals zum Interrupt Vektor springt und den Stack nicht 
freigibt.

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.