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?
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.
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?
Philip K. schrieb: > Vielleicht hat > ja jemand einen Tipp, wie man solchen Fehlern auf die Schliche kommt? Debugger?
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
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?
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.
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.
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 ------------------------------------------------------------------------ --
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.
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
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.
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.
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
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?
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.