mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik FreeRTOS: Critical section und blockierender Queue


Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgender Code zum Senden eines Bytes stammt aus dem UART-Beispiel von
FreeRTOS:
  portENTER_CRITICAL();
  {
    /* Is there space to write directly to the UART? */
    if( *plTHREEmpty == ( portLONG ) pdTRUE )
    {
      /* We wrote the character directly to the UART, so was 
      successful. */
      *plTHREEmpty = pdFALSE;
      UART0_THR = cOutChar;
      xReturn = pdPASS;
    }
    else 
    {
      /* We cannot write directly to the UART, so queue the character.
      Block for a maximum of xBlockTime if there is no space in the
      queue. */
      /* was passiert wenn dieser Queue blockt? context switch? */
      xReturn = xQueueSend( xCharsForTx, &cOutChar, xBlockTime );

      /* Depending on queue sizing and task prioritisation:  While we 
      were blocked waiting to post interrupts were not disabled.  It is 
      possible that the serial ISR has emptied the Tx queue, in which
      case we need to start the Tx off again. */
      if( ( *plTHREEmpty == ( portLONG ) pdTRUE ) && ( xReturn == pdPASS )
)
      {
        xQueueReceive( xCharsForTx, &cOutChar, serNO_BLOCK );
        *plTHREEmpty = pdFALSE;
        UART0_THR = cOutChar;
      }
    }
  }
  portEXIT_CRITICAL();

Was mir nicht ganz klar ist: CRITICAL unterbindet ja preemtive
Kontextwechsel. Was passiert aber wenn xQueueSend blockiert? Findet
dann ein Kontextwechsel statt, oder werden alle Tasks komplett
angehalten?

Andreas

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrekt erkannt, das sollte man so nicht machen.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur: Es geht, weil das Interrupt-Flag ein Bestandteil vom
Task-Kontext ist. Da xQueueSend ggf. einen Taskwechsel durchführt, wird
als Teil dieses Taskwechsels der Interrupt wieder eingeschaltet. Das
muss man Auge behalten, wenn man bei abgeschalteten Interrupts Routinen
aufruft, die blockieren können.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"CRITICAL unterbindet ja preemtive Kontextwechsel"

Das ja, aber kooperative Taskwechsel sind erlaubt. Und xQueueSend
enthält einen solchen

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha, das erklärt auch den Satz "While we were blocked waiting to post
interrupts were not disabled.". Während der Task blockiert laufen die
anderen Tasks also ganz normal weiter und unterbrechen sich ggf. auch
preemtiv gegenseitig, und bei der Rückkehr in den blockierten Task sind
die Interrupts wieder deaktiviert. Kann man das so stehen lassen?

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtig.

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.