Forum: Compiler & IDEs Flag in ISR und main


von TechInfo (Gast)


Lesenswert?

Frage in der main ein Flag (cmdRcvd) in einer Schleife ab und setze es 
danach wieder auf 0.
1
(....)
2
3
while(1)
4
  {
5
    if (cmdRcvd) {
6
      print(cmdBuffer);
7
      print("\n");
8
      cmdRcvd=0;
9
    }

Das Flag wird in der ISR gesetzt, wenn ein bestimmter Befehl über RS232 
eingegangen ist:
1
while (!XUartLite_mIsReceiveEmpty(XPAR_RS232_BASEADDR))
2
  {  
3
    do 
4
    {  
5
      s[i] = XUartLite_RecvByte(XPAR_RS232_BASEADDR);
6
      i++;
7
    }
8
    while (s[i-1]!='\r');
9
    s[i]='\0';
10
    cmdRcvd=1;

Jetzt könnte es ja aber sein, dass ein UART-Interrupt in der main z.B. 
bei der Anweisung print ("\n") auftritt. Dadurch würde dann zunächst das 
Flag gesetzt, wenn der Prozessor zurück springt und an der letzten 
Stelle weiter macht wird es aber gelöscht. Somit findet im nächsten 
Schleifendurchlauf keine Verarbeitung des Strings statt.

Wie kann man das lösen?

von TechInfo (Gast)


Lesenswert?

Genügt es, dass Rücksetzen des Flags direkt nach der if-Abfrage zu 
machen?

von Simon K. (simon) Benutzerseite


Lesenswert?

Schau dir mal sei() und cli() an. (Vorausgesetzt wir reden hier über 
AVRs)

>Genügt es, dass Rücksetzen des Flags direkt nach der if-Abfrage zu
>machen?

Nein.

von Wolfram (Gast)


Lesenswert?

>Wie kann man das lösen?
In einem Zustand darf immer nur EINER schreibend auf das Flag zugreifen.

von TechInfo (Gast)


Lesenswert?

Wir reden nicht über AVRs, aber du meinst wohl, ich solle vor der 
Abfrage des Flags die Interrupts deaktiveren und danach wieder 
aktivieren. Dann gehen mir aber unter Umständen RS232-Kommandos 
verloren.

von Werner B. (Gast)


Lesenswert?

> Dann gehen mir aber unter Umständen RS232-Kommandos
verloren.

Wie schnell sendest du den Kommandos?

Bei 115200 bps dauert ein Byte (asynchron, deshalb 10 Bit)
10/115200 Sekunden  = ca. 86,8 Microsekunden.
Ein RISC Prozessor mit 8MHz arbeitet in dieser Zeit ca. 700 Befehle ab.
Und aktuelle UARTs haben mindestens ein Byte Buffer.
Du bist nicht der Erste der sich darüber Gedanken macht ;-)

Werner

von TechInfo (Gast)


Lesenswert?

Ok, hab's kapiert ;)

von TechInfo (Gast)


Lesenswert?

Dennoch bietet es sich an, das Flag direkt nach der if-Abfrage zurück zu 
setzen, und währenddessen eben die Interrupts zu deaktivieren, oder?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

http://de.wikipedia.org/wiki/Mutex

=>

http://de.wikipedia.org/wiki/Lock

=>

Die ISR will einen Write-Lock auf die Resource 'cmdBuffer' setzen und 
der Anweisungsblock in main (bzw. ähnliche Auswerteblocks) einen 
Read-Lock

Vermutlich hast du noch eine dritte Stelle im Programmcode, wo ein 
Write-Lock notwendig ist - die Stelle wo 'cmdBuffer' gelöscht bzw. 
zurückgesetzt wird.

von TechInfo (Gast)


Lesenswert?

Interessante Links.

Was ist nun besser, die Interrupts ausschalten oder einen 
Lock-Algorithmus implementieren?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Pinzette oder Holzhammer...

Vom lerntechnischen her ist sicher Mutex/Lock besser ;-) und wenn ein 
Sperren der Interrupts programmtechnisch nicht in Frage kommt.

Vom Code/Codieren her ist das Sperren/Freigeben des Interrupts 
wahrscheinlich einfacher zu machen.

...das hängt vom Patienten ab.


von TechInfo (Gast)


Lesenswert?

Hm, die beschriebenen Methoden beziehen sich ja auf Prozesse, die also 
gleichberechtigt sind.

Bei einer Interruptroutine verhält es sich aber anders: Wenn ich dort 
wie unter dem zweiten Link beschrieben eine Warte-Routine einfüge, 
springt er mir trotzdem aus dem Hauptprogramm und bleibt dann für immer 
und ewig in der ISR hängen, weil eben das Hauptprogramm nicht 
gleichberechtigt weiterläuft und irgendwann die Ressource wieder frei 
gibt.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Korrekt erkannt.

Du musst dir überlegen, was mit deiner Resource cmdBuffer passieren 
soll, wenn im Moment kein Zugriff möglich ist. Eine aktive Warteschleife 
in der ISR ist in der Tat tödlich.

Die Frage stellt sich derzeit auch. Angenommen printf ist dabei 
cmdBuffer auszugeben und die ISR springt an. Darf die ISR dann cmdBuffer 
selbst oder den Inhalt ändern?

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.