www.mikrocontroller.net

Forum: Compiler & IDEs Flag in ISR und main


Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frage in der main ein Flag (cmdRcvd) in einer Schleife ab und setze es 
danach wieder auf 0.
(....)

while(1)
  {
    if (cmdRcvd) {
      print(cmdBuffer);
      print("\n");
      cmdRcvd=0;
    }

Das Flag wird in der ISR gesetzt, wenn ein bestimmter Befehl über RS232 
eingegangen ist:
while (!XUartLite_mIsReceiveEmpty(XPAR_RS232_BASEADDR))
  {  
    do 
    {  
      s[i] = XUartLite_RecvByte(XPAR_RS232_BASEADDR);
      i++;
    }
    while (s[i-1]!='\r');
    s[i]='\0';
    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?

Autor: TechInfo (Gast)
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Wolfram (Gast)
Datum:

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

Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, hab's kapiert ;)

Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessante Links.

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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.


Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.