Forum: Mikrocontroller und Digitale Elektronik Wie beim HW-Debuggen einen Interrupt manuell auslösen?


von Sternd (Gast)


Lesenswert?

Moin,

ich debugge aktuell mein Projekt unter Microchip Studio v7.0.132 mit 
einem Atmel-Ice auf einem ATMega32 (ateval 2.0). jetzt möchte ich u.a. 
meine UART-ISR testen und dazu manuell (=kontrolliert) einen der 
relevanten INT auslösen. Ich möchte dies am besten über IDE/Debugger 
erledigen und nicht durch das tatsächliche Senden eines Zeichens über 
die RS232.

Habe jetzt schon reichlich gegoogelt, aber nichts konkretes gefunden, 
mag sein, das es an unglücklichen Suchbegriffen liegt.
Soweit ich verstanden habe, geht das schon mal nicht im Single Step, 
daher ist ein BP in der ISR erforderlich - ok.

Aber gibt es eine Möglichkeit, ein INT-Flag händisch zu setzen, z.B. 
bevor man den Debugger mit F5 weiterlaufen läßt?

Danke vorab für hilfreiche Vorschläge und Gruß

von Bratmaxxe (Gast)


Lesenswert?

Manuell den RS232 Pin auf High ziehen sollte reichen.

von Bernd S. (sternd)


Lesenswert?

Moin,
du meinst die Pins RXD bzw. TXD am MC auf high setzen? Wie soll das zu 
einem USART_RX-INT bzw. USART_TX-INT führen? Da mußt du mir bitte auf 
die Sprünge helfen.
Und dann wäre da ja noch der USART_UDRE-INT, den ich auch gerne 
simulieren würde.

MFG

von jo mei (Gast)


Lesenswert?

Sternd schrieb:
> und dazu manuell (=kontrolliert) einen der
> relevanten INT auslösen

Das machst du gaaaaanz einfach indem du an einem PC Terminal
genau ein Zeichen an deinen Controller sendest.

Alles andere ist einfach nur dümmlich umständlich und fehlerbehaftet.

von Bernd S. (sternd)


Lesenswert?

Genau das will ich aber aus bestimmten, guten Gründen nicht. Also suche 
ich eine andere Lösung.
Zudem, damit kann ich zwar RX aber nicht TX oder UDRE testen.

> Alles andere ist einfach nur dümmlich umständlich und fehlerbehaftet.
Darüber würde ich mir gerne selbst ein Bild machen.

: Bearbeitet durch User
von jemand (Gast)


Lesenswert?

Was hast du denn vor, damit zu testen?
Die Hardware hat ja nichts empfangen, daher können sich die anderen 
Register nicht, falls du globale Flags setzt, geht das auch mit dem 
Debugger und testen, ob dein Interrupt auslöst, kannst du so sich nicht.
Du könntest noch die Funktion (oder die Funktionalität gekapselt) selbst 
aufrufen (vielleicht geht das auch aus dem Debugger, indem man den PC 
setzt?), aber das wäre auch wieder nicht das gleiche.

von Achim M. (minifloat)


Lesenswert?

Man kann durch ein Flag in einem if(){} in der Mainloop einfach den 
Interrupthandler aufrufen. Aber bringts das? Und was soll dann im 
UDR-Register stehen?

mfg mf

von Bernd S. (sternd)


Lesenswert?

jemand schrieb:
> Was hast du denn vor, damit zu testen?

Ich versuch mich mal in einer Erläuterung:
Ich habe in c++ eine Klasse zur seriellen Kommunikation geschrieben, 
welche die relevanten ISR als eigene Methoden kapselt. Von diese Klasse 
instanziere ich nun in einer anderen Klasse ein Objekt. Bisher hat die 
übergeordnete Klasse noch keine weiteren Methoden. Also passiert nix, 
solange nicht die UART-INTs triggern.
Irgendwie hängt aber mein Programm derzeit und ich sehe nicht, ob die 
INTs richtig erkannt und die entsprechenden ISR-Methoden richtig 
aufgerufen werden.
Daher möchte ich beim debuggen gezielt TX/RX/UDRE-INT aufrufen, um zu 
sehen, ob die ISR korrekt aufgerufen werden. Daß dann noch nix im UDR 
steht, ist also im Moment noch Wumpe.
Das ganze Vorgehen dient darüberhinaus als Blaupause für weitere INTs, 
die ich später mal verwenden werde und die dann nix mit dem UART zu tun 
haben.

Meine Hoffnung ist (oder war?), daß man im Studio über den Debugger, 
also Atmel-Ice, die INTs manuell auslösen kann.

von jemand (Gast)


Lesenswert?

Selbst wenn das geht, wäre (notfalls auf einem separaten Board) ein 
minimal Example da doch aussagekräftiger, oder?
Mangling und sowas hast du vermutlich beachtet, oder?

von W.S. (Gast)


Lesenswert?

Bernd S. schrieb:
> Ich versuch mich mal in einer Erläuterung:
> Ich habe in c++ eine Klasse zur seriellen Kommunikation geschrieben,
> welche die relevanten ISR als eigene Methoden kapselt.

Immer mal wieder so ein Versuch. Und immer wieder funktioniert es eher 
schlecht als recht. Und oftmal garnicht.

Nein, zum Benutzen von Hardware schreibt man einen Treiber und versucht 
nicht, das in eine Objekt-Klasse zu pressen.

W.S.

Beitrag #6899931 wurde vom Autor gelöscht.
von Bernd S. (sternd)


Lesenswert?

jemand schrieb:
> Mangling und sowas hast du vermutlich beachtet, oder?
yup

von Bernd S. (sternd)


Lesenswert?

W.S. schrieb:
> Bernd S. schrieb:
> Nein, zum Benutzen von Hardware schreibt man einen Treiber und versucht
> nicht, das in eine Objekt-Klasse zu pressen.

Wenn man OOP programmieren will, dann konsequent und sauber, sonst macht 
der ganze OOP-Krams nur wenig bis keinen Sinn. Und für OOP gibt's aus 
anderen Erwägungen auch gute Gründe. Also sehe ich das keinesfalls so 
fundamental wie du.

Und überhaupt war meine Frage ja auch, ob es eine manuelle INT-Auslösung 
gibt, nicht wie ihr das findet, oder wie ihr die UART-Programmierung in 
OOP findet.

von Bernd S. (sternd)


Lesenswert?

Achim M. schrieb:
> Man kann durch ein Flag in einem if(){} in der Mainloop einfach den
> Interrupthandler aufrufen.

wie das?

von Carsten S. (dg3ycs)


Lesenswert?

Sternd schrieb:
> Aber gibt es eine Möglichkeit, ein INT-Flag händisch zu setzen, z.B.
> bevor man den Debugger mit F5 weiterlaufen läßt?

Für deinen konkreten Fall kann ich es nicht sicher sagen, da ich es zum 
einen bisher vorgezogen habe Interrups "natürlich" auszulösen (um nicht 
auf irgendwelche "Lustigen Effekte" hereinzufallen) und andererseits 
weder  ATMEL/Microchip Studio 7 noch einen ICE nutze, ich es also gerade 
nicht testen kann. Zumal die AVR nicht meine Lieblingsfamilie sind...

Aber hast du schon einmal versucht einfach das RXC Flag im UCSRA 
Register händisch im Memory-View zu editieren? Da auf das Register im 
Programmcode direkt zugegriffen werden kann sollte das auch beim 
Debuggen problemlos von HAnd möglich sein.

Ob dadurch aber tatsächlich ein Interrupt ausgelöst wird und wie sich 
das bei doch leerem Empfangsregister auswirken würde (das meine ich mit 
"lustige Seiteneffekte, meist passiert ja noch etwas mehr als das nur 
"EIN" Bit seinen Zustand ändert) kann ich nicht sagen.

ALternativ könnte man mal versuchen ob sich direkt ein Datenbyte in das 
HW-Empfangsregister editieren lässt (bei vielen µC geht DAS aber nicht) 
und was das bewirken würde.

Gruß
Carsten

von Cartman (Gast)


Lesenswert?

> Ich habe in c++

Es war ja fast klar, dass solch geistiges Blendwerk im Spiel ist.

Es kann nicht funktionieren, weil:
> Die Hardware hat ja nichts empfangen

von Bernd S. (sternd)


Lesenswert?

Carsten S. schrieb:
> Aber hast du schon einmal versucht einfach das RXC Flag im UCSRA
> Register händisch im Memory-View zu editieren?

Guter Hinweis, grundsätzlich löst das setzen dieses Flags wohl den INT 
aus, genauso wie die Pendants zu TX und UDRE. Allerdings habe ich bis 
jetzt noch keine Möglichkeit im Debug-Mode von Microchip Studio 
gefunden, dieses oder andere Flags von Hand zu setzen.
Ggfls., wie Achim schrieb, in main das Flag SW-seitig setzen, wäre dann 
ja in etwa so, wie gedacht. Das werde ich morgen mal probieren.

von c-hater (Gast)


Angehängte Dateien:

Lesenswert?

Bernd S. schrieb:

> Guter Hinweis, grundsätzlich löst das setzen dieses Flags wohl den INT
> aus, genauso wie die Pendants zu TX und UDRE.

Das ist das übliche Verhalten von Interruptflags, dazu gibt es sie. 
Allerdings muss natürlich das jeweils zugehörige Interrupt-Enable-Bit 
ebenfalls gesetzt sein und auch das globale Interupt-Enable-Bit.

> Allerdings habe ich bis
> jetzt noch keine Möglichkeit im Debug-Mode von Microchip Studio
> gefunden, dieses oder andere Flags von Hand zu setzen.

Es gibt schon etliche Bits in der Hardware, die man von Hand setzen 
kann, RXC und UDRE gehören aber nicht dazu. Das kann man bereits im 
Datenblatt erkennen. Siehe Anhang. Die rot eingekreisten "R" stehen für 
"readable". Sprich: man kann diese Bits nicht schreiben, das sind reine 
Ausgänge der Statuslogik der UART-Hardware.

Bei TXC liegt die Sache etwas anders, da steht "R/W", was "readable and 
writable" bedeutet. Allerdings ist das auch hier kein normales 
Schreiben. Man kann dieses Flag nicht setzen, sondern nur löschen, indem 
man eine logische 1 hier rein schreibt. Ein sog. Strobe-Bit. Leider 
unterscheidet das Datenblatt in diesen hüschen übersichtlichen Grafiken 
nicht zwischen normal schreibbaren Bits und Strobe-Bits. Man muß den 
Text lesen, um heraus zu bekommen, dass es sich um ein Strobe-Bit 
handelt.

Zusammenfassung: du kannst keins der UART-Interrupflags "von Hand" 
setzen, weder mit dem Debugger noch aus dem Programm heraus. Du musst 
die UART mit Daten füttern. Allerdings gibt es wieder eine Ausnahme: 
UDRE ist von vornherein gesetzt, sobald der UART-Sender aktiviert wird. 
Hier musst du die UART mit Daten füttern, um es gelöscht zu bekommen.

Zusammefassung der Zusammenfassung: steht alles im Datenblatt. Man muss 
es nur lesen!

von Bernd S. (sternd)


Lesenswert?

Alles soweit bekannt...
die Hoffnung war, daß es eine mir unbekannte Möglichkeit gäbe, auch die 
externen INTs durch einen SW-Befehl zu "imitieren". Sowas hab ich schon 
mal an andere Stelle gesehen und dachte, vllt. gibt's das ja auch bei 
den Atmels. OK, ist nicht so.

von jo mei (Gast)


Lesenswert?

Bernd S. schrieb:
> OK, ist nicht so.

Bernd S. schrieb:
> Darüber würde ich mir gerne selbst ein Bild machen.

Zusammenfassend rückblickend betrachtet wolltest du also lieber
von hinten durch die Brust ins Auge anstatt von straight forward.

Eine plausible Begründung für deine Abwege wären vielleicht
hilfreich gewesen zu verstehen warum du das willst.

Ich frage mich jedoch was es (nach deiner beabsichtigten Methode)
bringen soll einen Interrupt abzuarbeiten ohne dass ein Zeichen
eingetroffen ist.

von Bernd S. (sternd)


Lesenswert?

jo mei schrieb:

> Zusammenfassend rückblickend betrachtet wolltest du also lieber
> von hinten durch die Brust ins Auge anstatt von straight forward.
>
> Eine plausible Begründung für deine Abwege wären _vielleicht_
> hilfreich gewesen zu verstehen warum du das willst.

Warum muß ich eine für dich plausible Begründung haben?! Ich habe aus 
einem von außen betrachtet irrelevanten Anlaß eine klare technische 
Frage gehabt und um die klären, muß nur die Frage verständlich sein, 
mehr nicht. Ich habe ja nicht nach Alternativen zu meinem Vorgehen 
oder nach einer Bewertung desselben gefragt.
So wie ich das sehe, haben c_hater, Carsten, jemand oder Achim auch 
keine Probleme gehabt, mir auf eine technische Frage eine technische 
Antwort zu geben.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Bernd S. schrieb:
> die Hoffnung war, daß es eine mir unbekannte Möglichkeit gäbe, auch die
> externen INTs durch einen SW-Befehl zu "imitieren".

Also, das ist ein ziemlich sinnwidriges Ansinnen. Flags, die ein 
Peripheriecore in ein lesbares Register leitet, sind zum Lesen da und 
gelegentlich müssen die per Schreibbefehl auch noch gelöscht werden.

Was also stellst du dir vor, mit so einer Aktion zu bewirken? Etwa den 
betreffenden Core in einen anderen Zustand zu bringen, als er von sich 
aus hat?

Lies stattdessen das Manual zu deinem Chip und sieh zu, daß du einen 
passenden Treiber dafür konzipierst. Dann kontrolliere dein Geschreibsel 
nochmal und wenn du richtig gelesen und sorgfältig geschrieben hast, 
dann funktioniert der Treiber dann auch. Aber das bedeutet, daß du das 
Ganze zuvor richtig konzipiert hast - und zwar nach den Anforderungen 
der Hardware und nicht nach irgendwelchen Software-Ideen.

W.S.

von W.S. (Gast)


Lesenswert?

Bernd S. schrieb:
> Warum muß ich eine für dich plausible Begründung haben?! Ich habe aus
> einem von außen betrachtet irrelevanten Anlaß eine klare technische
> Frage gehabt und um die klären, muß nur die Frage verständlich sein,
> mehr nicht.

Also, mein Lieber, das heißt mit anderen Worten: "Ich will genau hier 
mit dem Kopf durch die Wand springen, hole mir dabei aber nur eine 
Beule. Etwaige Ratschläge, um ohne Beule durch die Wand zu kommen oder 
ein Hinweis auf eine vorhandene Tür lehne ich kategorisch ab, weil ich 
danach nicht gefragt habe."

Wenn Leute bereit sind, so einem wie dir zu helfen, dann muß dein Ziel 
denen wenigstens verständlich erscheinen. Einfach nur so eine Frage zu 
stellen und eine dir zusagende Antwort zu erwarten, ist ein bissel 
daneben. Dies ist ein Forum zum Diskutieren und kein Cola-Automat.

W.S.

von Achim M. (minifloat)


Lesenswert?

Bernd S. schrieb:
> Achim M. schrieb:
>
>> Man kann durch ein Flag in einem if(){} in der Mainloop einfach den
>> Interrupthandler aufrufen.
>
> wie das?

Der Interrupthandler, eine Funktion, auf die ein Zeiger in der 
Interrupttabelle zeigt. Man kann sie aufrufen, wie auch jede andere 
"void (void)" Funktion. Ob nach RTI alles wie vorher weiterläuft, statt 
wie bei einer normalen Funktion mit RTS, und nicht der Stack kaputt ist, 
da habe ich kein Wort drüber verloren ;)

mfg mf

von Bernd S. (sternd)


Lesenswert?

W.S. schrieb:
> Flags, die ein
> Peripheriecore in ein lesbares Register leitet, sind zum Lesen da und
> gelegentlich müssen die per Schreibbefehl auch noch gelöscht werden.
Lesen hilft...
Ich habe nicht geschrieben, ich wolle durch einen SW-Befehl *ein Flag 
setzen*, um so den INT zu imitieren. Da gäbe es genug andere 
theoretische Möglichkeiten, eine solche Funktionalität zu 
implementieren. Von anderer HW kennen ich das, da war die Hoffnung 
durchaus legitim, auch beim Atmel fündig zu werden.
Im übrigen, der Vorschlag, Flags zu setzen wurde von mir nicht in diesen 
Thread eingebracht.

> Was also stellst du dir vor, mit so einer Aktion zu bewirken? Etwa den
> betreffenden Core in einen anderen Zustand zu bringen, als er von sich
> aus hat?
Ähm -- ja, das macht jeder Programmcode Zeile für Zeile, ist der Sinn 
von Programmen.

Also, es reicht völlig, wenn du feststellst, daß du keine solche 
Möglichkeit, wie von mir angefragt, kennst. Tu dir nicht den Zwang an, 
einen Sachverhalt zu diskutieren, den ich nicht dargelegt habe oder mir 
zu erzählen, was ich zu tun oder zu lassen habe, ohne überhaupt zu 
wissen, was ich bisher getan oder gelassen habe.

von Bernd S. (sternd)


Lesenswert?

W.S. schrieb:

> Wenn Leute bereit sind, so einem wie dir zu helfen, dann muß dein Ziel
> denen wenigstens verständlich erscheinen.
Nö, nicht im geringsten
> Einfach nur so eine Frage zu
> stellen und eine dir zusagende Antwort zu erwarten, ist ein bissel
> daneben. Dies ist ein Forum zum Diskutieren und kein Cola-Automat.
Ich habe keine mir zusagende Antwort erwartet und denke, das läßt sich 
auch aus keinem meiner Postings so herauslesen. Wenn du das eine oder 
andere Wording anders verstanden hast, bedaure ich das. Aber, ich habe 
nicht um Ratschläge für mein generelles Vorgehen gebeten, sondern um 
eine Antwort auf eine klare technische Frage. Über die technischen 
Aspekte läßt sich bereits reichlich genug diskutieren und das ist auch 
gut so. Aber ich muß mir nicht den Streß antun, mein Vorgehen hier lang 
und breit zu erklären, wenn es der Beantwortung einer technischen Frage 
kein Stück weiterhilft.

Vllt. überschätzt du einfach den Bedarf, von dir allumfassend beraten zu 
werden?

von Bernd S. (sternd)


Lesenswert?

ok Achim, jetzt hab ich deinen Punkt
das Stichwort "Flag" hatte mich iritiert

: Bearbeitet durch User
von LedJongleur (Gast)


Lesenswert?

Bernd S. schrieb:
> Zudem, damit kann ich zwar RX aber nicht TX oder UDRE testen.

Im Datenblatt zum ATmega siehst du doch im Kapitel USART / Register 
description welche Bits in welchem Register R(ead only) bzw. R/W sind.
Wenn das Bit als 'R' deklariert ist, sieht es wohl düster aus. Bleibt 
nur das Gehäuse bis zum Die abschleifen und an der richtigen Stelle eine 
Käbelchen anzubonden.

von Bernd S. (sternd)


Lesenswert?

LedJongleur schrieb:
> Bernd S. schrieb:
>> Zudem, damit kann ich zwar RX aber nicht TX oder UDRE testen.
>
> Im Datenblatt zum ATmega siehst du doch im Kapitel USART / Register
> description welche Bits in welchem Register R(ead only) bzw. R/W sind.
> Wenn das Bit als 'R' deklariert ist, sieht es wohl düster aus. Bleibt
> nur das Gehäuse bis zum Die abschleifen und an der richtigen Stelle eine
> Käbelchen anzubonden.

Na daß ist doch mal ein praktikabler Vorschlag xD,

: Bearbeitet durch User
von Wühlhase (Gast)


Lesenswert?

Bernd S. schrieb:
> Warum muß ich eine für dich plausible Begründung haben?! Ich habe aus
> einem von außen betrachtet irrelevanten Anlaß eine klare technische
> Frage gehabt und um die klären, muß nur die Frage verständlich sein,
> mehr nicht. Ich habe ja nicht nach Alternativen zu meinem Vorgehen
> oder nach einer Bewertung desselben gefragt.

Die Sache ist halt die: Oft kommen Anfänger mit einem Problem, 
beschreiben aber (nur) ihren Ansatz den sie nicht zum Laufen bekommen.
Und jemand, der sich auskennt, sieht daß das sehr umständlich, 
fehlerträchtig oder in anderer Weise Mist ist.

Da ist es normal (und normalerweise erfolgreicher), das Problem selber 
zu kennen.

Allzumal du im Threadtitel was von HW-Debugging schreibst, du aber mit 
einer reinen Softwareangelegenheit kommst.

Und ja: Wäre das mein Problem würde ich zusehen, eine richtige 
UART-Gegenstelle zu bekommen. Vielleicht gäbe es auch einen Weg, die 
Hardware zu simulieren und für jede Klasse einen Unittest zu schreiben, 
dann wäre das der Weg den ich vorziehen würde.

von Achim M. (minifloat)


Lesenswert?

Bernd S. schrieb:
> ok Achim, jetzt hab ich deinen Punkt
> das Stichwort "Flag" hatte mich iritiert

Ja sorry... Software-Flag, weil man Interruptflags i.a. nur löschen kann 
:)

mfg nf

von Bernd S. (sternd)


Lesenswert?

Wühlhase schrieb:

> Da ist es normal (und normalerweise erfolgreicher), das Problem selber
> zu kennen.
Ja, wenn ich eine Lsg. für mein gesamtes Problem (INT in OOP) gesucht 
hätte, würde ich dir auf jeden Fall recht geben, aber ich wollte einfach 
nur eine technische Frage erörtern.

> Allzumal du im Threadtitel was von HW-Debugging schreibst, du aber mit
> einer reinen Softwareangelegenheit kommst.
Naja, mir ging es darum, ob überhaupt und ggfls. wie ich beim 
HW-Debugging einen INT "simulieren" kann. Ob über SW, wie später im 
Thread angedacht, oder über einen "Schalter" im Debug-Mode war mir da 
gleich.

> Und ja: Wäre das mein Problem würde ich zusehen, eine richtige
> UART-Gegenstelle zu bekommen. Vielleicht gäbe es auch einen Weg, die
> Hardware zu simulieren und für jede Klasse einen Unittest zu schreiben,
> dann wäre das der Weg den ich vorziehen würde.
Die HW ist ja da, das ist gar nicht das Problem und den RXC kann ich 
natürlich mittels Putty triggern. Aber der Test für TXC/UDRE oder später 
andere INTs hätte u.U. einfacher werden können, aber alles nur 
Konjunktiv.

von Peter D. (peda)


Lesenswert?

Man kann doch einfach mehrere Vektoren auf den selben Interrupthandler 
zeigen lassen:
ISR_ALIAS(vector, target_vector).
Dann kann man z.B. mit einem externen Interrupt den UART-Handler 
ausführen.
Man kann auch einen SW-Interrupt emulieren, z.B. den SPM-Interrupt 
enablen, der wird ausgeführt, solange SELFPRGEN gelöscht ist.

Typisch braucht man solchen Firlefanz aber nicht, sondern richtet je 
UART 2 FIFOs ein. Die FIFOS testet man einmal, ob sie das Rollover und 
Überläufe korrekt abhandeln und kapselt bei Bedarf (FIFO >256 Byte) die 
kritischen Zugriffe atomar.

von Bernd S. (sternd)


Lesenswert?

W.S. schrieb:
> Bernd S. schrieb:
>> Warum muß ich eine für dich plausible Begründung haben?! Ich habe aus
>> einem von außen betrachtet irrelevanten Anlaß eine klare technische
>> Frage gehabt und um die klären, muß nur die Frage verständlich sein,
>> mehr nicht.
>
> Also, mein Lieber, das heißt mit anderen Worten: "Ich will genau hier
> mit dem Kopf durch die Wand springen, hole mir dabei aber nur eine
> Beule.

Deine Analyse der Situation fehlt. Ich hole mir doch keine Beule, wenn 
ich einen technischen Sachverhalt eruiere und dabei auf die Grenzen des 
Angedachten hingewiesen werde. Schon mal was von technischer Neugier 
gehört?!

von W.S. (Gast)


Lesenswert?

Bernd S. schrieb:
> Schon mal was von technischer Neugier
> gehört?!

Also, du meinst, daß du aus technischer Neugier gegen die Wand springst, 
um mal selber zu erleben, wie sich die Beule so anfühlt?

Nun denn, tue was du nicht lassen kannst. Mir kommen da die Shadoks in 
den Sinn. pumpen, pumpen....

W.S.

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.