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ß
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
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.
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.
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.
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
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.
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?
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.
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.
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
> 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
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.
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!
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.
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.
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.
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.
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.
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
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.
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?
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.
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,
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.
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
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.
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.
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?!
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.