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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren