FreeRTOS: Critical section und blockierender Queue

OP Admin Persönliche Seite #324429
Lesenswert?
• ▲
▼
Hallo,

folgender Code zum Senden eines Bytes stammt aus dem UART-Beispiel von
FreeRTOS:
1
  portENTER_CRITICAL();
2
  {
3
    /* Is there space to write directly to the UART? */
4
    if( *plTHREEmpty == ( portLONG ) pdTRUE )
5
    {
6
      /* We wrote the character directly to the UART, so was 
7
      successful. */
8
      *plTHREEmpty = pdFALSE;
9
      UART0_THR = cOutChar;
10
      xReturn = pdPASS;
11
    }
12
    else 
13
    {
14
      /* We cannot write directly to the UART, so queue the character.
15
      Block for a maximum of xBlockTime if there is no space in the
16
      queue. */
17
      /* was passiert wenn dieser Queue blockt? context switch? */
18
      xReturn = xQueueSend( xCharsForTx, &cOutChar, xBlockTime );
19

20
      /* Depending on queue sizing and task prioritisation:  While we 
21
      were blocked waiting to post interrupts were not disabled.  It is 
22
      possible that the serial ISR has emptied the Tx queue, in which
23
      case we need to start the Tx off again. */
24
      if( ( *plTHREEmpty == ( portLONG ) pdTRUE ) && ( xReturn == pdPASS )
25
)
26
      {
27
        xQueueReceive( xCharsForTx, &cOutChar, serNO_BLOCK );
28
        *plTHREEmpty = pdFALSE;
29
        UART0_THR = cOutChar;
30
      }
31
    }
32
  }
33
  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
Gast #324431
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.
OP Admin Persönliche Seite #324433
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?

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.