Hallo Zusammen,
im Rahmen einer Projektarbeit bin ich gerade dabei den Industriell
Ethernet Controller "R-IN32M3-CL" der Firma Renesas in Betrieb zunehmen
und zu verstehen. Für die Inbetriebnahme stellt Renesas einige
Samplecodes zur Verfügung. Mit den Samplecodes funktioniert der
Controller problemlos in meinem Netzwerk; ich kann Daten zur SPS(Master)
senden und von dieser empfangen.
Zur Erklärung des Samplecodes hat Renesas nun ein "Developing Flowchart"
im Manual (Seite 54)zur Verfügung gestellt. Allerdings gibt es einen
Funktionsaufruf im Flowchart den ich nicht ganz verstehe. Der Abschnitt
"Event processing" ist mir ein absolutes Rätsel. Weder der Quellcode
noch das Flowchart für das "Event processing" (Seite 60) gibt mir
aufschluss über die Funktionsweise. Besonders die Funktionen
"gerR_IN32_GetEvent" und "gerR_IN32_Main" bereiten mit Kopfschmerzen ...
Die Funktion "gerR_IN32_GetEvent", greift auf auf die Struktur
"R_IN32_EVTPRM_INTERRUPT_T" zu (Seite 111), aber was dann passiert, kann
ich mir nicht erklären. Wie genau arbeitet die Funktion mit der
Struktur? Überprüft sie ob ein Interrupt ausgelöst wurde?
Ich habe das Manual beigefügt in dem die Funktionen erklärt sind.
Vielleicht versteht jemand mehr als ich und könnte es mir erklären? Des
Weiteren habe ich das "Event processing" aus dem Samplecode im Anhang
hinzugefügt.
Bitte entschuldigt, wenn ich das Problem nur schlecht schildern konnte,
falls irgendwas unklar ist, erkläre ich es sehr gerne nochmal. Ich
bedanke mich jedoch recht herzlich für jede Hilfe !
Schöne Grüße
Moe Espunkt
Kann man anhand dieser zwei Quellcodeausschnitte sagen, wie hier der
Interrupt funktionieren soll? Irgendwas muss ja die Ursache für den
Interrupt sein?
Ich wäre für eure Hilfe sehr dankbar, zumal weil ich kurz vor der
Verzweiflung bin...
Schöne Grüße und vielen Dank im Voraus.
Ich denke, du klammerst dich momentan zusehr am Wort 'Interrupt' fest.
Wenn ein Interrupt auftritt, dann wird von der eigentlichen
Behandlungsroutine eine entsprechender Eintrag in einer Warteschlange
gemacht, um festzuhalten, dass dieses Ereignis aufgetreten ist.
gerR_IN32_GetEvent macht nichts anderes, als in dieser Warteschlange
(auch Queue genannt) nachzusehen, ob es einen Eintrag gibt und wenn ja
wird die übergebene R_IN32_EVTPRM_INTERRUPT_T Struktur entsprechend
ausgefüllt. Könnte auch sein, dass die Queue selbst schone entsprechende
Struktur Objekte enthält. Das ist aber nicht dein Bier, wie das
systemintern gehandhabt wird.
> Irgendwas muss ja die Ursache für den Interrupt sein?
Schau dir Flags in der Struktur an. Genau der jeweils damit verbundene
Vorgang ist es, der von irgendeinem Handler behandelt wird und dazu
führt, dass ein entsprechender Eintrag in der Event-Queue gemacht wird.
Das Wort bzw. die Bezeichnung 'Interrupt' im Strukturnamen verführt dich
jetzt dazu, viel zu kompliziert zu denken. Zu dem Zeitpunkt, an dem du
mittels gerR_IN32_GetEvent zum ersten mal deine Finger an die
Information kriegst, dass die Kommunikation unterbrochen wurde (das
b1ZCommDisconnect Bit ist gesetzt), ist das entsprechende Ereignis bzw.
der dadurch ausgelöste Interrupt schon lange Vergangenheit. Das Ereignis
wurde (vom Handler) in der Queue zur geschätzten Kenntnissnahme
registriert und das wars dann auch schon. Das "Ereignis" lungert dann
solange in der Queue rum, bis du es mittels gerR_IN32_GetEvent abholst
und irgendwelche Reaktionen darauf machst.
Das ganze ist von der grundsätzlichen Architektur keineswegs
ungewöhnlich. Auch Windows arbeitet im Grunde so. Für jeden Prozess gibt
es eine Queue und wenn irgendetwas auftritt (zb der Benutzer hat mit der
Maus geklickt, eine Taste wurde gedrückt, ein Fenster wurde verschoben),
werden entsprechende Nachrichten in diese Queue gestellt. Jeder Prozess
hat als zentrales Elemente die Behandlung dieser Message Queue, in der
eine Message von der Queue geholt wird (wenn es eine gibt) und
entsprechend der Message dann behandelt wird. Auch wenn die diversen
Frameworks das alles unter vielen Softwareschichten verborgen haben, im
Grunde funktioniert das alles immer noch so wie anno dazumal zu Windows
3.0 Zeiten, in der man als C-Programmierer direkt mit dieser
Message-Pumpe in Berührung kam.
Bei Windows heisst das ganze dann eben 'Message', hier heisst es 'Event'
und die Struktur würde besser R_IN32_EVTPRM_EVENT_T heissen und nichts
mit einem 'INTERRUPT' im Namen. Sieh dir die Verwendung an
1
R_IN32_EVTPRM_INTERRUPT_TstEvent;
die Variable heißt 'Event' und nicht Interrupt. Die Funktion
1
...gerR_IN32_GetEvent
heißt Get Event. Event(!) und nicht Get Interrupt.
Schlussfolgerung: die Struktur hätte besser auch ein EVENT im Namen
gehabt und kein INTERRUPT. Das solche Events durch Interrupts entstehen
können, ist ja schön. Interessiert aber den Applikationsprogrammierer
nicht. Der arbeitet mit Events und nicht mit Interrupts. Wenn die Dinge
gefühlt falsch benannt sind, führt das des öfteren schon mal zu
Verwirrung, weil die Dinge scheinbar nicht zusammenpassen.
> im Grunde funktioniert das alles immer noch so wie anno dazumal zu> Windows 3.0 Zeiten, in der man als C-Programmierer direkt mit dieser> Message-Pumpe in Berührung kam.
Genau, und ich bin dankbar, dass ich diese Sachen noch von Grund auf
lernen durfte.
Heutzutage müssen Programmierer ihren Job so schnell erlernen, dass die
Zeit fehlt, sich mit solchen Grundlagen überhaupt zu beschäftigen. Das
finde ich schade.
Aber genau deswegen begrüße ich den inzwischen leicht gewordenen Zugang
zu Mikrocontrollern. Denn wenn man die programmiert, kommt man doch
wieder zu den Grundlagen - nur über einen anderen Weg. Ich finde, dass
jeder Programmierer sich irgendwann mal mit einer Mikrocontroller
Anwendung OHNE SOFTWARE FRAMEWORK beschäftigen sollte.
Hallo Karl Heinz,
also erst einmal vielen vielen Dank für deine wirklich sehr hilfreiche
Antwort!!
Also wenn ich das jetzt richtig verstanden habe, dann wird (irgednwo...
ist auch erst einmal egal wo und wie)ein Interrupt ausgelöst. Dieser
Interrupt hinterlässt einen Eintrag in der Queue und
"gerR_IN32_GetEvent" macht nichts anderes als nach zu schauen ob in der
Queue ein Eintrag (von einem Interrupt) hinterlassen wurden ist.
Wenn sich ein Eintrag in der Queue befindet, so wird das in die Strukur
eingetragen (bzw. das Bit wird gesetzt).
Dann macht der Funktionsaufruf, welcher nach "gerR_IN32_GetEvent" kommt:
1
/* main process of R_IN32M3 event detection */
2
gerR_IN32_Main(&stEvent);
auch völlig sinn!! Denn diese Funktion überprüft nämlich, ob etwas in
der Struktur eingetragen ist und wenn ja , dann führt diese Funktion die
passende Reaktion auf diesen Eintrag aus. Dann ist natürlich fraglich,
wo die Reaktion auf das jeweilige gesetzte Bit in der Strukur, definiert
ist? Ist mein Gedankengang denn soweit richtig?
Karl Heinz schrieb:> im> Grunde funktioniert das alles immer noch so wie anno dazumal zu Windows> 3.0 Zeiten, in der man als C-Programmierer direkt mit dieser> Message-Pumpe in Berührung kam.
Ich behaupte mal dass ich 21 jähriger in einer Zeit lebe, in der man
sich die elementaren Grundlagen selbst erarbeiten muss. Korrigiert mich
bitte wenn ich falsch liege, aber der Trend geht immer mehr in Richtung
"fertige Bausteine !! Fertige Funktionen!! Bloß nicht mit den Grundlagen
beschäftigen!!"
Finde ich sehr schade ...
Moe Espunkt schrieb:> Dann macht der Funktionsaufruf, welcher nach "gerR_IN32_GetEvent" kommt:>>
1
/* main process of R_IN32M3 event detection */
2
>gerR_IN32_Main(&stEvent);
>> auch völlig sinn!! Denn diese Funktion überprüft nämlich, ob etwas in> der Struktur eingetragen ist und wenn ja , dann führt diese Funktion die> passende Reaktion auf diesen Eintrag aus. Dann ist natürlich fraglich,> wo die Reaktion auf das jeweilige gesetzte Bit in der Strukur, definiert> ist? Ist mein Gedankengang denn soweit richtig?
Klingt logisch.
Das hier ist zb die zentrale Message-Pump in einem Windows-Programm
1
while((bRet=GetMessage(&msg,NULL,0,0))!=0)
2
{
3
if(bRet==-1)
4
{
5
// Handle Error
6
}
7
else
8
{
9
TranslateMessage(&msg);
10
DispatchMessage(&msg);
11
}
12
}
Im Grunde sind alle Zutaten völlig analog zu deinen vorhanden.
Einziger Unterschied: die Windows Message Pump läuft durch die
while-Schleife solange, bis sie einen WM_QUIT erhält, der dem Programm
signalisiert, sich zu beenden, wodurch es aus der while-Schleife
rausfällt und damit auch aus main().
Bei dir ist das eben ein bischen anders organsiert. Aber die
Bestandteile "Event (Message) holen", "Event (Message) bearbeiten" sind
da wie dort genau gleich vorhanden. Da gibt es keinen prinzipiellen
Unterschied.
Ahh!! Ich verstehe! Zwar ist die Struktur eine andere aber die
prinzipielle Funktionsweise ist im Grunde die selbe !! Ich danke dir
recht herzlich für deine Bemühungen Karl Heinz.
Aber mal Hand auf's Herz: Woher weiß man sowas, wenn man nicht gerade
Software Engineering studiert?
Moe Espunkt schrieb:> ... aber die prinzipielle Funktionsweise ist im Grunde die selbe !! ...
Ganz wichtiges Prinzip:
Alle kochen schon seit Jahrzehnten auch nur mit immer dem gleichen
Wasser :-)
> Aber mal Hand auf's Herz: Woher weiß man sowas, wenn man nicht gerade> Software Engineering studiert?
:-)
'Man' ist damit aufgewachsen.